Skip to content

Commit

Permalink
Etching Tool (#959)
Browse files Browse the repository at this point in the history
* Updated the foundry dev tools to support etching onto Sepolia

* Fixed the etching tools

* Added `DebugTest.sol`

* Cleaned up the debugging tools

* Updated the information to be a successful `ERC4626` call

* Updated CI

* Fixed the spell-check linter

* Removed goerli from the repo

* Added a README

* Addressed review feedback from @jrhea
  • Loading branch information
jalextowle authored Apr 11, 2024
1 parent c56556c commit ae1cd7e
Show file tree
Hide file tree
Showing 11 changed files with 327 additions and 17 deletions.
2 changes: 1 addition & 1 deletion .env_template
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# ethereum rpc endpoints used in fork tests and migration scripts
GOERLI_RPC_URL=
MAINNET_RPC_URL=
SEPOLIA_RPC_URL=

# private key used for running migration scripts
PRIVATE_KEY=
2 changes: 1 addition & 1 deletion .github/workflows/benchmark.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ jobs:
needs: detect-changes
if: needs.detect-changes.outputs.changed == 'true'
env:
GOERLI_RPC_URL: ${{ secrets.GOERLI_RPC_URL }}
MAINNET_RPC_URL: ${{ secrets.MAINNET_RPC_URL }}
SEPOLIA_RPC_URL: ${{ secrets.SEPOLIA_RPC_URL }}
steps:
# Install the dependencies.
- uses: actions/checkout@v2
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ jobs:
needs: detect-changes
if: needs.detect-changes.outputs.changed == 'true'
env:
GOERLI_RPC_URL: ${{ secrets.GOERLI_RPC_URL }}
MAINNET_RPC_URL: ${{ secrets.MAINNET_RPC_URL }}
SEPOLIA_RPC_URL: ${{ secrets.SEPOLIA_RPC_URL }}
steps:
- uses: actions/checkout@v3
with:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/solidity_lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ jobs:
needs: detect-changes
if: needs.detect-changes.outputs.changed == 'true'
env:
GOERLI_RPC_URL: ${{ secrets.GOERLI_RPC_URL }}
MAINNET_RPC_URL: ${{ secrets.MAINNET_RPC_URL }}
SEPOLIA_RPC_URL: ${{ secrets.SEPOLIA_RPC_URL }}
steps:
- uses: actions/checkout@v3
with:
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/solidity_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ jobs:
needs: detect-changes
if: needs.detect-changes.outputs.changed == 'true'
env:
GOERLI_RPC_URL: ${{ secrets.GOERLI_RPC_URL }}
MAINNET_RPC_URL: ${{ secrets.MAINNET_RPC_URL }}
SEPOLIA_RPC_URL: ${{ secrets.SEPOLIA_RPC_URL }}
steps:
- uses: actions/checkout@v3
with:
Expand All @@ -39,8 +39,8 @@ jobs:
needs: detect-changes
if: needs.detect-changes.outputs.changed == 'true'
env:
GOERLI_RPC_URL: ${{ secrets.GOERLI_RPC_URL }}
MAINNET_RPC_URL: ${{ secrets.MAINNET_RPC_URL }}
SEPOLIA_RPC_URL: ${{ secrets.SEPOLIA_RPC_URL }}
steps:
- uses: actions/checkout@v3
with:
Expand All @@ -61,8 +61,8 @@ jobs:
needs: detect-changes
if: needs.detect-changes.outputs.changed == 'true'
env:
GOERLI_RPC_URL: ${{ secrets.GOERLI_RPC_URL }}
MAINNET_RPC_URL: ${{ secrets.MAINNET_RPC_URL }}
SEPOLIA_RPC_URL: ${{ secrets.SEPOLIA_RPC_URL }}
steps:
- uses: actions/checkout@v3
with:
Expand All @@ -83,8 +83,8 @@ jobs:
needs: detect-changes
if: needs.detect-changes.outputs.changed == 'true'
env:
GOERLI_RPC_URL: ${{ secrets.GOERLI_RPC_URL }}
MAINNET_RPC_URL: ${{ secrets.MAINNET_RPC_URL }}
SEPOLIA_RPC_URL: ${{ secrets.SEPOLIA_RPC_URL }}
steps:
- uses: actions/checkout@v3
with:
Expand Down
3 changes: 3 additions & 0 deletions cSpell.json
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,9 @@
"sdiv",
"secp",
"selfdestruct",
"sepolia",
"Sepolia",
"SEPOLIA",
"Sighash",
"sload",
"sloads",
Expand Down
2 changes: 1 addition & 1 deletion foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,4 @@ runs = 1000

[rpc_endpoints]
mainnet = "${MAINNET_RPC_URL}"
goerli = "${GOERLI_RPC_URL}"
sepolia = "${SEPOLIA_RPC_URL}"
81 changes: 81 additions & 0 deletions test/debug/Debugging.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.8.20;

import { console2 as console } from "forge-std/console2.sol";
import { IHyperdrive } from "contracts/src/interfaces/IHyperdrive.sol";
import { ETH } from "contracts/src/libraries/Constants.sol";
import { BaseTest } from "test/utils/BaseTest.sol";
import { EtchingUtils } from "test/utils/EtchingUtils.sol";

/// @author DELV
/// @title Debugging
/// @notice A test suite to help debugging on Sepolia or Mainnet.
/// @custom:disclaimer The language used in this code is for coding convenience
/// only, and is not intended to, and does not, have any
/// particular legal or regulatory significance.
contract Debugging is BaseTest, EtchingUtils {
/// @dev The block to fork. If you're debugging a failing transaction, this
/// should be the block at which the transaction was failing. If you're
/// debugging a successful transaction, you may need to subtract one
/// from the block.
uint256 internal constant FORK_BLOCK = 5676348;

/// @dev The hyperdrive instance to connect to. If you're debugging a
/// Hyperdrive transaction, this should probably be the `to` address in
/// the failing transaction.
IHyperdrive internal constant HYPERDRIVE =
IHyperdrive(address(0x392839dA0dACAC790bd825C81ce2c5E264D793a8));

/// @dev The sender to use in the debugging call. If you're debugging a
/// Hyperdrive transaction, this should probably be the `from`
/// address in the failing transaction.
address internal constant SENDER =
address(0x2C76cc659ec83E36323f32E6a9789C29e7b56c4B);

/// @dev The value to use in the debugging call. If you're debugging a
/// Hyperdrive transaction, this should probably be the `value`
/// sent in the failing transaction.
uint256 internal constant VALUE = 0;

/// @dev The calldata to use in the debugging call. If you're debugging a
/// Hyperdrive transaction, this should probably be the calldata from
/// the failing transaction (remove the "0x" prefix from the calldata).
bytes internal constant CALLDATA =
hex"cba2e58d0000000000000000000000000000000000000000000007d9a5405edc26fa36b50000000000000000000000000000000000000000000007d7f3c7d8d354cd71990000000000000000000000000000000000000000000000000de326f195450cd200000000000000000000000000000000000000000000000000000000000000800000000000000000000000002c76cc659ec83e36323f32e6a9789c29e7b56c4b0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000";

function test_debug() external __sepolia_fork(FORK_BLOCK) {
// Etch the hyperdrive instance to add console logs.
if (HYPERDRIVE.baseToken() == ETH) {
etchStETHHyperdrive(address(HYPERDRIVE));
} else {
etchERC4626Hyperdrive(address(HYPERDRIVE));
}

// Log a preamble.
console.log("---------------");
console.log("-- Debugging --");
console.log("---------------");
console.log("");
console.log("[test_debug] Sending the debugging call...");
console.log("");

// Debugging the transaction.
vm.startPrank(address(SENDER));
(bool success, bytes memory returndata) = address(HYPERDRIVE).call{
value: VALUE
}(CALLDATA);

// Log a summary.
if (success) {
console.log(
"[test_debug] The call succeeded and returned the following returndata: %s",
vm.toString(returndata)
);
} else {
console.log(
"[test_debug] The call failed and returned the following returndata: %s",
vm.toString(returndata)
);
}
}
}
47 changes: 47 additions & 0 deletions test/debug/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Debugging

This folder contains a testing utility that can be used to debug Hyperdrive
transactions on the sepolia testnet. To use this tool, update the constants in
`test/debug/Debugging.t.sol` with the values from the transaction you'd like to
debug. In particular, you'll need to set the fork block, the hyperdrive address,
the transaction value, and the transaction calldata. Once you've done this, you
can run the following command to run the debugging tool:

```
forge test -vv --match-test "test_debug"
```

To get more insight into what went wrong (or right) during the transaction
execution, you can add some `console.log` statements in the Hyperdrive codebase
and re-run the tests. Assuming the logs are in the execution path of the debug
transaction, you'll see these logs when you re-run the test.

## Tips

1. To add `console.log` statements, you'll need to import `console2` from
`forge-std/console2.sol` in each file that you add logs to.
2. You can pretty-print fixed point numbers with the `Lib.toString` function
from `test/utils/Lib.sol`. You can add `using Lib for *;` on the line after
the contract declaration to use method syntax like `value.toString(18)`. The
`18` in this example indicates that the fixed point value has 18 decimals.
3. Start by adding some `console.log` statements to the start of the flow that
you're calling. You can find the start of the core flows in the following
files:
- `HyperdriveLong`: `_openLong`, `_closeLong`
- `HyperdriveShort`: `_openShort`, `_closeShort`
- `HyperdriveLP`: `_addLiquidity`, `_removeLiquidity`, `_redeemWithdrawalShares`
- `HyperdriveCheckpoint`: `_checkpoint`
4. If you want to inspect what happened during `_deposit` or `_withdraw`, you
may need to add logs to the appropriate `Base` contract for the integration
that you're using. If you're debugging a stETH yield source, add logs to
`_depositWithBase`, `_depositWithShares`, or one of the other functions in
`contracts/src/instances/steth/StETHBase.sol`. Similarly, if you're debugging
an ERC4626 yield source (like sDAI), you can add logs to the corresponding
functions in `contracts/src/instances/erc4626/ERC4626Base.sol`.
5. If you want to inspect what happened within the yield source, you can add logs
to `contracts/test/MockLido.sol` if you're debugging a stETH yield source or
to `contracts/test/MockERC4626.sol` if you're debugging an ERC4626 yield
source (like sDAI).
6. If you want to inspect what happened within the base token, you can add logs
to `contracts/test/ERC20Mintable.sol`. Note that the base token for stETH is
a placeholder since stETH uses ETH as a base token.
13 changes: 5 additions & 8 deletions test/utils/BaseTest.sol
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,10 @@ contract BaseTest is Test {
error WhaleBalanceExceeded();
error WhaleIsContract();

uint256 mainnetForkId;
uint256 goerliForkId;

uint256 __init__; // time setup function was ran

string MAINNET_RPC_URL = vm.envString("MAINNET_RPC_URL");
string GOERLI_RPC_URL = vm.envString("GOERLI_RPC_URL");
string SEPOLIA_RPC_URL = vm.envString("SEPOLIA_RPC_URL");

bool isForked;

Expand All @@ -53,17 +50,17 @@ contract BaseTest is Test {
}

modifier __mainnet_fork(uint256 blockNumber) {
mainnetForkId = vm.createFork(MAINNET_RPC_URL);
uint256 mainnetForkId = vm.createFork(MAINNET_RPC_URL);
vm.selectFork(mainnetForkId);
vm.rollFork(blockNumber);
isForked = true;

_;
}

modifier __goerli_fork(uint256 blockNumber) {
goerliForkId = vm.createFork(GOERLI_RPC_URL);
vm.selectFork(goerliForkId);
modifier __sepolia_fork(uint256 blockNumber) {
uint256 sepoliaForkId = vm.createFork(SEPOLIA_RPC_URL);
vm.selectFork(sepoliaForkId);
vm.rollFork(blockNumber);
isForked = true;

Expand Down
Loading

0 comments on commit ae1cd7e

Please sign in to comment.