Skip to content

Commit

Permalink
test: add test for receivedelegation special case
Browse files Browse the repository at this point in the history
Signed-off-by: Tomás Migone <[email protected]>
  • Loading branch information
tmigone committed Aug 23, 2024
1 parent afe8bbc commit 7d1b2fb
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 25 deletions.
30 changes: 15 additions & 15 deletions packages/horizon/test/staking/HorizonStaking.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -290,9 +290,9 @@ contract HorizonStakingTest is HorizonStakingSharedTest, IHorizonStakingTypes {
vm.store(address(staking), bytes32(uint256(serviceProviderBaseSlot) + 4), bytes32(_tokensProvisioned));
}

function _slash(uint256 tokens, uint256 verifierCutAmount) internal {
uint256 beforeProviderTokens = staking.getProviderTokensAvailable(users.indexer, subgraphDataServiceAddress);
uint256 beforeDelegationTokens = staking.getDelegatedTokensAvailable(users.indexer, subgraphDataServiceAddress);
function _slash(address serviceProvider, address verifier, uint256 tokens, uint256 verifierCutAmount) internal {
uint256 beforeProviderTokens = staking.getProviderTokensAvailable(serviceProvider, verifier);
uint256 beforeDelegationTokens = staking.getDelegatedTokensAvailable(serviceProvider, verifier);
bool isDelegationSlashingEnabled = staking.isDelegationSlashingEnabled();

// Calculate expected tokens after slashing
Expand All @@ -306,40 +306,40 @@ contract HorizonStakingTest is HorizonStakingSharedTest, IHorizonStakingTypes {
vm.expectEmit(address(staking));
if (verifierCutAmount > 0) {
emit IHorizonStakingMain.VerifierTokensSent(
users.indexer,
subgraphDataServiceAddress,
subgraphDataServiceAddress,
serviceProvider,
verifier,
verifier,
verifierCutAmount
);
}
emit IHorizonStakingMain.ProvisionSlashed(users.indexer, subgraphDataServiceAddress, providerTokensSlashed);
emit IHorizonStakingMain.ProvisionSlashed(serviceProvider, verifier, providerTokensSlashed);

if (isDelegationSlashingEnabled) {
emit IHorizonStakingMain.DelegationSlashed(
users.indexer,
subgraphDataServiceAddress,
serviceProvider,
verifier,
delegationTokensSlashed
);
} else {
emit IHorizonStakingMain.DelegationSlashingSkipped(
users.indexer,
subgraphDataServiceAddress,
serviceProvider,
verifier,
delegationTokensSlashed
);
}
staking.slash(users.indexer, tokens, verifierCutAmount, subgraphDataServiceAddress);
staking.slash(serviceProvider, tokens, verifierCutAmount, verifier);

if (!isDelegationSlashingEnabled) {
expectedDelegationTokensAfterSlashing = beforeDelegationTokens;
}

uint256 provisionTokens = staking.getProviderTokensAvailable(users.indexer, subgraphDataServiceAddress);
uint256 provisionTokens = staking.getProviderTokensAvailable(serviceProvider, verifier);
assertEq(provisionTokens, expectedProviderTokensAfterSlashing);

uint256 delegationTokens = staking.getDelegatedTokensAvailable(users.indexer, subgraphDataServiceAddress);
uint256 delegationTokens = staking.getDelegatedTokensAvailable(serviceProvider, verifier);
assertEq(delegationTokens, expectedDelegationTokensAfterSlashing);

uint256 verifierTokens = token.balanceOf(subgraphDataServiceAddress);
uint256 verifierTokens = token.balanceOf(verifier);
assertEq(verifierTokens, verifierCutAmount);
}

Expand Down
4 changes: 2 additions & 2 deletions packages/horizon/test/staking/delegation/delegate.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ contract HorizonStakingDelegateTest is HorizonStakingTest {
_delegate(users.indexer, subgraphDataServiceAddress, delegationTokens, 0);

resetPrank(subgraphDataServiceAddress);
_slash(tokens + delegationTokens, 0);
_slash(users.indexer, subgraphDataServiceAddress, tokens + delegationTokens, 0);

resetPrank(users.delegator);
token.approve(address(staking), delegationTokens);
Expand All @@ -101,7 +101,7 @@ contract HorizonStakingDelegateTest is HorizonStakingTest {
_undelegate(users.indexer, subgraphDataServiceAddress, delegation.shares);

resetPrank(subgraphDataServiceAddress);
_slash(tokens + delegationTokens, 0);
_slash(users.indexer, subgraphDataServiceAddress, tokens + delegationTokens, 0);

resetPrank(users.delegator);
token.approve(address(staking), delegationTokens);
Expand Down
2 changes: 1 addition & 1 deletion packages/horizon/test/staking/delegation/undelegate.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ contract HorizonStakingUndelegateTest is HorizonStakingTest {
_delegate(users.indexer, subgraphDataServiceAddress, delegationTokens, 0);

resetPrank(subgraphDataServiceAddress);
_slash(tokens + delegationTokens, 0);
_slash(users.indexer, subgraphDataServiceAddress, tokens + delegationTokens, 0);

resetPrank(users.delegator);
Delegation memory delegation = _getDelegation(subgraphDataServiceAddress);
Expand Down
2 changes: 1 addition & 1 deletion packages/horizon/test/staking/delegation/withdraw.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ contract HorizonStakingWithdrawDelegationTest is HorizonStakingTest {
skip(MAX_THAWING_PERIOD + 1);

resetPrank(subgraphDataServiceAddress);
_slash(tokens + delegationTokens, 0);
_slash(users.indexer, subgraphDataServiceAddress, tokens + delegationTokens, 0);

resetPrank(users.delegator);
vm.expectRevert(abi.encodeWithSelector(
Expand Down
8 changes: 4 additions & 4 deletions packages/horizon/test/staking/slash/slash.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ contract HorizonStakingSlashTest is HorizonStakingTest {
vm.assume(verifierCutAmount <= maxVerifierTokens);

vm.startPrank(subgraphDataServiceAddress);
_slash(slashTokens, verifierCutAmount);
_slash(users.indexer, subgraphDataServiceAddress, slashTokens, verifierCutAmount);
}

function testSlash_DelegationDisabled_SlashingOverProviderTokens(
Expand All @@ -52,7 +52,7 @@ contract HorizonStakingSlashTest is HorizonStakingTest {
_delegate(users.indexer, subgraphDataServiceAddress, delegationTokens, 0);

vm.startPrank(subgraphDataServiceAddress);
_slash(slashTokens, verifierCutAmount);
_slash(users.indexer, subgraphDataServiceAddress, slashTokens, verifierCutAmount);
}

function testSlash_DelegationEnabled_SlashingOverProviderTokens(
Expand All @@ -71,7 +71,7 @@ contract HorizonStakingSlashTest is HorizonStakingTest {
_delegate(users.indexer, subgraphDataServiceAddress, delegationTokens, 0);

vm.startPrank(subgraphDataServiceAddress);
_slash(slashTokens, verifierCutAmount);
_slash(users.indexer, subgraphDataServiceAddress, slashTokens, verifierCutAmount);
}

function testSlash_OverProvisionSize(
Expand All @@ -83,7 +83,7 @@ contract HorizonStakingSlashTest is HorizonStakingTest {
vm.assume(slashTokens > tokens + delegationTokens);

vm.startPrank(subgraphDataServiceAddress);
_slash(slashTokens, 0);
_slash(users.indexer, subgraphDataServiceAddress, slashTokens, 0);
}

function testSlash_RevertWhen_NoProvision(
Expand Down
36 changes: 34 additions & 2 deletions packages/horizon/test/staking/transfer-tools/ttools.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,35 @@ contract HorizonStakingTransferToolsTest is HorizonStakingTest {
_onTokenTransfer_ReceiveDelegation(counterpartStaking, amount, data);
}

function testOnTransfer_ReceiveDelegation_WhenInvalidPool(uint256 amount) public useDelegationSlashing(true) {
amount = bound(amount, 1 ether, MAX_STAKING_TOKENS);
uint256 originalDelegationAmount = 10 ether;
uint256 provisionSize = 100 ether;

// create provision and legacy delegation pool - this is done by the bridge when indexers move to L2
resetPrank(users.indexer);
_createProvision(subgraphDataServiceLegacyAddress, provisionSize, 0, 1 days);

// initialize the delegation pool
resetPrank(users.delegator);
_delegateLegacy(users.indexer, originalDelegationAmount);

// slash the entire provision
resetPrank(subgraphDataServiceLegacyAddress);
_slash(users.indexer, subgraphDataServiceLegacyAddress, provisionSize + originalDelegationAmount, 0);

// send amount to staking contract - this should be done by the bridge
resetPrank(users.delegator);
token.transfer(address(staking), amount);

resetPrank(graphTokenGatewayAddress);
bytes memory data = abi.encode(
uint8(IL2StakingTypes.L1MessageCodes.RECEIVE_DELEGATION_CODE),
abi.encode(users.indexer, users.delegator)
);
_onTokenTransfer_ReceiveDelegation(counterpartStaking, amount, data);
}

/**
* HELPERS
*/
Expand Down Expand Up @@ -128,8 +157,11 @@ contract HorizonStakingTransferToolsTest is HorizonStakingTest {
? tokens
: ((tokens * beforePool.shares) / (beforePool.tokens - beforePool.tokensThawing));

bool earlyExit = (calcShares == 0 || tokens < 1 ether) ||
(beforePool.tokens == 0 && (beforePool.shares != 0 || beforePool.sharesThawing != 0));

// onTokenTransfer
if (calcShares == 0 || tokens < 1 ether) {
if (earlyExit) {
vm.expectEmit();
emit Transfer(address(staking), delegator, tokens);
vm.expectEmit();
Expand Down Expand Up @@ -158,7 +190,7 @@ contract HorizonStakingTransferToolsTest is HorizonStakingTest {
uint256 deltaShares = afterDelegation.shares - beforeDelegation.shares;

// assertions
if (calcShares == 0 || tokens < 1 ether) {
if (earlyExit) {
assertEq(beforePool.tokens, afterPool.tokens);
assertEq(beforePool.shares, afterPool.shares);
assertEq(beforePool.tokensThawing, afterPool.tokensThawing);
Expand Down

0 comments on commit 7d1b2fb

Please sign in to comment.