Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
137 changes: 40 additions & 97 deletions test/units/hyperdrive/CloseLongTest.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,12 @@ contract CloseLongTest is HyperdriveTest {
initialize(alice, apr, contribution);

// Open a long position.
uint256 baseAmount = 10e18;
uint256 basePaid = 10e18;
(uint256 maturityTime, uint256 bondAmount) = openLong(
hyperdrive,
bob,
baseAmount
basePaid
);
uint256 checkpointTime = maturityTime - POSITION_DURATION;

// Get the reserves before closing the long.
PoolInfo memory poolInfoBefore = getPoolInfo(hyperdrive);
Expand All @@ -95,47 +94,11 @@ contract CloseLongTest is HyperdriveTest {
bondAmount
);

// Verify that all of Bob's bonds were burned and that he has
// approximately as much base as he started with.
assertEq(
hyperdrive.balanceOf(
AssetId.encodeAssetId(AssetId.AssetIdPrefix.Long, maturityTime),
bob
),
0
);
// Verify that bob doesn't end up with more than he started with
assertGe(baseAmount, baseProceeds);
// Verify that Bob didn't receive more base than he put in.
assertLe(baseProceeds, basePaid);

// Verify that the reserves were updated correctly. Since this trade
// happens at the beginning of the term, the bond reserves should be
// increased by the full amount.
PoolInfo memory poolInfoAfter = getPoolInfo(hyperdrive);
assertEq(
poolInfoAfter.shareReserves,
poolInfoBefore.shareReserves -
baseProceeds.divDown(poolInfoBefore.sharePrice)
);
assertEq(
poolInfoAfter.bondReserves,
poolInfoBefore.bondReserves + bondAmount
);
assertEq(poolInfoAfter.lpTotalSupply, poolInfoBefore.lpTotalSupply);
assertEq(poolInfoAfter.sharePrice, poolInfoBefore.sharePrice);
assertEq(
poolInfoAfter.longsOutstanding,
poolInfoBefore.longsOutstanding - bondAmount
);
assertEq(poolInfoAfter.longAverageMaturityTime, 0);
assertEq(poolInfoAfter.longBaseVolume, 0);
assertEq(hyperdrive.longBaseVolumeCheckpoints(checkpointTime), 0);
assertEq(
poolInfoAfter.shortsOutstanding,
poolInfoBefore.shortsOutstanding
);
assertEq(poolInfoAfter.shortAverageMaturityTime, 0);
assertEq(poolInfoAfter.shortBaseVolume, 0);
assertEq(hyperdrive.shortBaseVolumeCheckpoints(checkpointTime), 0);
// Verify that the close long updates were correct.
verifyCloseLong(poolInfoBefore, baseProceeds, bondAmount, maturityTime);
}

function test_close_long_immediately_with_small_amount() external {
Expand All @@ -146,13 +109,12 @@ contract CloseLongTest is HyperdriveTest {
initialize(alice, apr, contribution);

// Open a long position.
uint256 baseAmount = .01e18;
uint256 basePaid = .01e18;
(uint256 maturityTime, uint256 bondAmount) = openLong(
hyperdrive,
bob,
baseAmount
basePaid
);
uint256 checkpointTime = maturityTime - POSITION_DURATION;

// Get the reserves before closing the long.
PoolInfo memory poolInfoBefore = getPoolInfo(hyperdrive);
Expand All @@ -165,50 +127,13 @@ contract CloseLongTest is HyperdriveTest {
bondAmount
);

// Verify that all of Bob's bonds were burned and that he has
// approximately as much base as he started with.
assertEq(
hyperdrive.balanceOf(
AssetId.encodeAssetId(AssetId.AssetIdPrefix.Long, maturityTime),
bob
),
0
);
// Verify that bob doesn't end up with more than he started with
assertGe(baseAmount, baseProceeds);
// Verify that Bob didn't receive more base than he put in.
assertLe(baseProceeds, basePaid);

// Verify that the reserves were updated correctly. Since this trade
// happens at the beginning of the term, the bond reserves should be
// increased by the full amount.
PoolInfo memory poolInfoAfter = getPoolInfo(hyperdrive);
assertEq(
poolInfoAfter.shareReserves,
poolInfoBefore.shareReserves -
baseProceeds.divDown(poolInfoBefore.sharePrice)
);
assertEq(
poolInfoAfter.bondReserves,
poolInfoBefore.bondReserves + bondAmount
);
assertEq(poolInfoAfter.lpTotalSupply, poolInfoBefore.lpTotalSupply);
assertEq(poolInfoAfter.sharePrice, poolInfoBefore.sharePrice);
assertEq(
poolInfoAfter.longsOutstanding,
poolInfoBefore.longsOutstanding - bondAmount
);
assertEq(poolInfoAfter.longAverageMaturityTime, 0);
assertEq(poolInfoAfter.longBaseVolume, 0);
assertEq(hyperdrive.longBaseVolumeCheckpoints(checkpointTime), 0);
assertEq(
poolInfoAfter.shortsOutstanding,
poolInfoBefore.shortsOutstanding
);
assertEq(poolInfoAfter.shortAverageMaturityTime, 0);
assertEq(poolInfoAfter.shortBaseVolume, 0);
assertEq(hyperdrive.shortBaseVolumeCheckpoints(checkpointTime), 0);
// Verify that the close long updates were correct.
verifyCloseLong(poolInfoBefore, baseProceeds, bondAmount, maturityTime);
}

// TODO: Clean up these tests.
function test_close_long_redeem() external {
uint256 apr = 0.05e18;

Expand All @@ -217,13 +142,12 @@ contract CloseLongTest is HyperdriveTest {
initialize(alice, apr, contribution);

// Open a long position.
uint256 baseAmount = 10e18;
uint256 basePaid = 10e18;
(uint256 maturityTime, uint256 bondAmount) = openLong(
hyperdrive,
bob,
baseAmount
basePaid
);
uint256 checkpointTime = maturityTime - POSITION_DURATION;

// Get the reserves before closing the long.
PoolInfo memory poolInfoBefore = getPoolInfo(hyperdrive);
Expand All @@ -239,26 +163,45 @@ contract CloseLongTest is HyperdriveTest {
bondAmount
);

// Verify that all of Bob's bonds were burned and that he has
// approximately as much base as he started with.
// Verify that Bob received base equal to the full bond amount.
assertEq(baseProceeds, bondAmount);

// Verify that the close long updates were correct.
verifyCloseLong(poolInfoBefore, baseProceeds, bondAmount, maturityTime);
}

function verifyCloseLong(
PoolInfo memory poolInfoBefore,
uint256 baseProceeds,
uint256 bondAmount,
uint256 maturityTime
) internal {
uint256 checkpointTime = maturityTime - POSITION_DURATION;

// Verify that all of Bob's bonds were burned.
assertEq(
hyperdrive.balanceOf(
AssetId.encodeAssetId(AssetId.AssetIdPrefix.Long, maturityTime),
bob
),
0
);
assertEq(baseProceeds, bondAmount);

// Verify that the reserves were updated correctly. Since this trade
// is a redemption, there should be no changes to the bond reserves.
// Verify that the bond reserves were updated according to flat+curve.
// The adjustment should be equal to timeRemaining * bondAmount.
PoolInfo memory poolInfoAfter = getPoolInfo(hyperdrive);
uint256 timeRemaining = calculateTimeRemaining(maturityTime);
assertEq(
poolInfoAfter.bondReserves,
poolInfoBefore.bondReserves + timeRemaining.mulDown(bondAmount)
);

// Verify that the other states were correct.
assertEq(
poolInfoAfter.shareReserves,
poolInfoBefore.shareReserves -
bondAmount.divDown(poolInfoBefore.sharePrice)
baseProceeds.divDown(poolInfoBefore.sharePrice)
);
assertEq(poolInfoAfter.bondReserves, poolInfoBefore.bondReserves);
assertEq(poolInfoAfter.lpTotalSupply, poolInfoBefore.lpTotalSupply);
assertEq(poolInfoAfter.sharePrice, poolInfoBefore.sharePrice);
assertEq(
Expand Down
Loading