Skip to content

Commit

Permalink
Implemented reentrancy tests for the core Hyperdrive functions
Browse files Browse the repository at this point in the history
  • Loading branch information
jalextowle committed Jul 12, 2023
1 parent 2b57706 commit 335900f
Show file tree
Hide file tree
Showing 11 changed files with 268 additions and 60 deletions.
7 changes: 1 addition & 6 deletions contracts/src/HyperdriveBase.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.8.19;

import { ReentrancyGuard } from "solmate/utils/ReentrancyGuard.sol";
import { HyperdriveStorage } from "./HyperdriveStorage.sol";
import { IERC20 } from "./interfaces/IERC20.sol";
import { IHyperdrive } from "./interfaces/IHyperdrive.sol";
Expand All @@ -17,11 +16,7 @@ import { MultiToken } from "./token/MultiToken.sol";
/// @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.
abstract contract HyperdriveBase is
ReentrancyGuard,
MultiToken,
HyperdriveStorage
{
abstract contract HyperdriveBase is MultiToken, HyperdriveStorage {
using FixedPointMath for uint256;
using SafeCast for uint256;

Expand Down
12 changes: 10 additions & 2 deletions contracts/src/HyperdriveLP.sol
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,11 @@ abstract contract HyperdriveLP is HyperdriveTWAP {
uint256 _minOutput,
address _destination,
bool _asUnderlying
) external returns (uint256 baseProceeds, uint256 withdrawalShares) {
)
external
nonReentrant
returns (uint256 baseProceeds, uint256 withdrawalShares)
{
if (_shares == 0) {
revert IHyperdrive.ZeroAmount();
}
Expand Down Expand Up @@ -320,7 +324,11 @@ abstract contract HyperdriveLP is HyperdriveTWAP {
uint256 _minOutputPerShare,
address _destination,
bool _asUnderlying
) external returns (uint256 baseProceeds, uint256 sharesRedeemed) {
)
external
nonReentrant
returns (uint256 baseProceeds, uint256 sharesRedeemed)
{
// Perform a checkpoint.
uint256 sharePrice = _pricePerShare();
_applyCheckpoint(_latestCheckpoint(), sharePrice);
Expand Down
26 changes: 18 additions & 8 deletions contracts/src/HyperdriveLong.sol
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,20 @@ abstract contract HyperdriveLong is HyperdriveLP {
/// @param _asUnderlying If true the user is charged in underlying if false
/// the contract transfers in yield source directly.
/// Note - for some paths one choice may be disabled or blocked.
/// @return The number of bonds the user received
/// @return maturityTime The maturity time of the bonds.
/// @return bondProceeds The amount of bonds the user received
function openLong(
uint256 _baseAmount,
uint256 _minOutput,
address _destination,
bool _asUnderlying
) external payable nonReentrant isNotPaused returns (uint256) {
)
external
payable
nonReentrant
isNotPaused
returns (uint256 maturityTime, uint256 bondProceeds)
{
// Check that the message value and base amount are valid.
_checkMessageValue();
if (_baseAmount == 0) {
Expand All @@ -50,11 +57,14 @@ abstract contract HyperdriveLong is HyperdriveLP {

// Calculate the pool and user deltas using the trading function. We
// backdate the bonds purchased to the beginning of the checkpoint.
uint256 shareReservesDelta;
uint256 bondReservesDelta;
uint256 totalGovernanceFee;
(
uint256 shareReservesDelta,
uint256 bondReservesDelta,
uint256 bondProceeds,
uint256 totalGovernanceFee
shareReservesDelta,
bondReservesDelta,
bondProceeds,
totalGovernanceFee
) = _calculateOpenLong(shares, sharePrice);

// If the ending spot price is greater than or equal to 1, we are in the
Expand All @@ -76,7 +86,7 @@ abstract contract HyperdriveLong is HyperdriveLP {
_governanceFeesAccrued += totalGovernanceFee;

// Apply the open long to the state.
uint256 maturityTime = latestCheckpoint + _positionDuration;
maturityTime = latestCheckpoint + _positionDuration;
_applyOpenLong(
shareReservesDelta,
bondProceeds,
Expand All @@ -103,7 +113,7 @@ abstract contract HyperdriveLong is HyperdriveLP {
bondProceeds
);

return (bondProceeds);
return (maturityTime, bondProceeds);
}

/// @notice Closes a long position with a specified maturity time.
Expand Down
3 changes: 2 additions & 1 deletion contracts/src/HyperdriveStorage.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.8.19;

import { ReentrancyGuard } from "solmate/utils/ReentrancyGuard.sol";
import { IERC20 } from "./interfaces/IERC20.sol";
import { IHyperdrive } from "./interfaces/IHyperdrive.sol";
import { MultiTokenStorage } from "./token/MultiTokenStorage.sol";
Expand All @@ -11,7 +12,7 @@ import { MultiTokenStorage } from "./token/MultiTokenStorage.sol";
/// @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.
abstract contract HyperdriveStorage is MultiTokenStorage {
abstract contract HyperdriveStorage is ReentrancyGuard, MultiTokenStorage {
/// Tokens ///

/// @notice The base asset.
Expand Down
2 changes: 1 addition & 1 deletion contracts/src/interfaces/IHyperdriveWrite.sol
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ interface IHyperdriveWrite is IMultiTokenWrite {
uint256 _minOutput,
address _destination,
bool _asUnderlying
) external payable returns (uint256);
) external payable returns (uint256 maturityTime, uint256 bondProceeds);

function closeLong(
uint256 _maturityTime,
Expand Down
8 changes: 6 additions & 2 deletions script/OpenLong.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,18 @@ contract OpenLongScript is Script {

BASE.mint(msg.sender, 10_000e18);
BASE.approve(address(HYPERDRIVE), 10_000e18);
uint256 longAmount = HYPERDRIVE.openLong(
(uint256 maturityTime, uint256 longAmount) = HYPERDRIVE.openLong(
10_000e18,
0,
msg.sender,
true
);

console.log("Bob opened a long position of %s bonds", longAmount);
console.log(
"Bob opened a long position of %s bonds that matures in timestamp %s",
longAmount,
maturityTime
);
console.log(
"Bob's long balance is now %s bonds",
HYPERDRIVE.balanceOf(
Expand Down
Loading

0 comments on commit 335900f

Please sign in to comment.