Skip to content

Commit

Permalink
Add the self destruct attack to ynETH.spec.sol
Browse files Browse the repository at this point in the history
Update test name
  • Loading branch information
xhad committed Mar 29, 2024
1 parent ced5c5f commit 707f357
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 65 deletions.
67 changes: 2 additions & 65 deletions test/foundry/scenarios/ynETH-Scenarios.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,70 +39,7 @@ Objective: Test the distribution of staking rewards to a multisig.

Objective: Verify that ynETH correctly accounts for fund balances and withdrawals from EigenLayer.

## Invariant Scenarios
**Scenario 10:** Self-Destruct Attack

The following invariant scenarios are designed to verify the correct behavior of the ynETH contract in various usage scenarios. These scenarios should never fail, and if they do, it indicates there is an implementation issue somewhere in the protocol.
Objective: Ensure the system is not vulnerable to a self-destruct attack.

**Total Assets Consistency**

```solidity
assert(totalDepositedInPool + totalDepositedInValidators() == totalAssets());
```

**Exchange Rate Integrity**

```solidity
assert(exchangeAdjustmentRate >= 0 && exchangeAdjustmentRate <= BASIS_POINTS_DENOMINATOR);
```
**Share Minting Consistency**

```solidity
assert(totalSupply() == previousTotalSupply + mintedShares)
```

**User Shares Integrity**

```solidity
assert(balanceOf(user) == previousUserSharesBalance + newUserSharesBalance);
```

**Total Deposited Integrity**

```solidity
assert(totalDepositedInValidators() == previousTotalDeposited + newDeposit);
```

**Total Assets Integrity**

```solidity
assert(totalAssets() == previousTotalAssets + newDeposit);
```

**Total Balance Integrity**

```solidity
assert(address(yneth).balance() == previousBalance + newBalance);
```

**Deposit and Withdrawal Symmetry**

```solidity
uint256 sharesMinted = depositETH(amount);
assert(sharesMinted == previewDeposit(amount));
```

**Rewards Increase Total Assets**

```solidity
uint256 previousTotalAssets = totalAssets();
// Simulate receiving rewards
receiveRewards{value: rewardAmount}();
assert(totalAssets() == previousTotalAssets + rewardAmount);
```

**Authorized Access Control**

```solidity
// For any role-restricted operation
assert(msg.sender == authorizedRoleAddress);
```
37 changes: 37 additions & 0 deletions test/foundry/scenarios/ynETH.spec.sol
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,44 @@ contract YnETHScenarioTest8 is IntegrationBaseTest, YnETHScenarioTest3 {


}
}

contract YnETHScenarioTest10 is IntegrationBaseTest, YnETHScenarioTest3 {

/**
Scenario 10: Self-Destruct ETH Transfer Attack
Objective: Ensure the system is not vulnerable to a self-destruct attack.
*/

function test_ynETH_Scenario_9_Self_Destruct_Attack() public {

address sender = address(this);
// Deposit 32 ETH to ynETH and create a Staking Node with a Validator
(IStakingNode stakingNode,) = depositEth_and_createValidator();

// Amount of ether to send via self-destruct
uint256 amountToSend = 1 ether;
// Ensure the test contract has enough ether to send
vm.deal(sender, amountToSend);

// Address to send ether to - for example, the stakingNode or another address
address payable target = payable(address(stakingNode)); // or any other target address

// Create and send ether via self-destruct
// The SelfDestructSender contract is created with the amountToSend and immediately self-destructs,
// sending its balance to the target address.
address(new SelfDestructSender{value: amountToSend}(target));

vm.prank(actors.STAKING_NODES_ADMIN);
stakingNode.processWithdrawals(32 ether, address(stakingNode).balance);
}
}

// Add this contract definition outside of your existing contract definitions
contract SelfDestructSender {
constructor(address payable _target) payable {
selfdestruct(_target);
}
}


Expand Down

0 comments on commit 707f357

Please sign in to comment.