Skip to content

Commit

Permalink
Adjusts the time stretch calculation to hold the ratio of reserves co…
Browse files Browse the repository at this point in the history
…nstant (#716)

* Adjust the time stretch to hold the ratio of reserves constant across position durations

* Adds a test for the time stretch adjustment
  • Loading branch information
jalextowle authored Jan 8, 2024
1 parent 62cec39 commit f4aeeee
Show file tree
Hide file tree
Showing 24 changed files with 327 additions and 70 deletions.
10 changes: 8 additions & 2 deletions contracts/test/MockMultiToken.sol
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,10 @@ contract MockMultiToken is HyperdriveMultiToken, MockHyperdriveBase {
minimumTransactionAmount: 1e15,
positionDuration: 365 days,
checkpointDuration: 1 days,
timeStretch: HyperdriveUtils.calculateTimeStretch(0.05e18),
timeStretch: HyperdriveUtils.calculateTimeStretch(
0.05e18,
365 days
),
governance: address(0),
feeCollector: address(0),
fees: IHyperdrive.Fees({
Expand All @@ -81,7 +84,10 @@ contract MockMultiToken is HyperdriveMultiToken, MockHyperdriveBase {
minimumTransactionAmount: 1e15,
positionDuration: 365 days,
checkpointDuration: 1 days,
timeStretch: HyperdriveUtils.calculateTimeStretch(0.05e18),
timeStretch: HyperdriveUtils.calculateTimeStretch(
0.05e18,
365 days
),
governance: address(0),
feeCollector: address(0),
fees: IHyperdrive.Fees({
Expand Down
4 changes: 3 additions & 1 deletion script/DevnetMigration.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,9 @@ contract DevnetMigration is Script {
checkpointDuration: config.hyperdriveCheckpointDuration,
timeStretch: config
.hyperdriveTimeStretchApr
.calculateTimeStretch(),
.calculateTimeStretch(
config.hyperdrivePositionDuration
),
governance: config.admin,
feeCollector: config.admin,
fees: IHyperdrive.Fees({
Expand Down
15 changes: 12 additions & 3 deletions test/integrations/ERC4626Hyperdrive.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,10 @@ contract ERC4626HyperdriveTest is HyperdriveTest {
minimumTransactionAmount: 0.001e18,
positionDuration: 365 days,
checkpointDuration: 1 days,
timeStretch: HyperdriveUtils.calculateTimeStretch(apr),
timeStretch: HyperdriveUtils.calculateTimeStretch(
apr,
365 days
),
governance: alice,
feeCollector: bob,
fees: IHyperdrive.Fees(0, 0, 0, 0)
Expand Down Expand Up @@ -311,7 +314,10 @@ contract ERC4626HyperdriveTest is HyperdriveTest {
minimumTransactionAmount: 0.001e18,
positionDuration: 365 days,
checkpointDuration: 1 days,
timeStretch: HyperdriveUtils.calculateTimeStretch(apr),
timeStretch: HyperdriveUtils.calculateTimeStretch(
apr,
365 days
),
governance: alice,
feeCollector: bob,
fees: IHyperdrive.Fees(0, 0, 0, 0)
Expand Down Expand Up @@ -355,7 +361,10 @@ contract ERC4626HyperdriveTest is HyperdriveTest {
minimumTransactionAmount: 0.001e18,
positionDuration: 365 days,
checkpointDuration: 1 days,
timeStretch: HyperdriveUtils.calculateTimeStretch(0.01e18),
timeStretch: HyperdriveUtils.calculateTimeStretch(
0.01e18,
365 days
),
governance: alice,
feeCollector: bob,
fees: IHyperdrive.Fees(0, 0, 0, 0)
Expand Down
6 changes: 4 additions & 2 deletions test/integrations/ERC4626Validation.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@ abstract contract ERC4626ValidationTest is HyperdriveTest {

// Config changes required to support ERC4626 with the correct initial Share Price
IHyperdrive.PoolDeployConfig memory config = testDeployConfig(
FIXED_RATE
FIXED_RATE,
POSITION_DURATION
);
config.baseToken = underlyingToken;
uint256 contribution = 7_500e18;
Expand Down Expand Up @@ -123,7 +124,8 @@ abstract contract ERC4626ValidationTest is HyperdriveTest {
vm.startPrank(alice);

IHyperdrive.PoolDeployConfig memory config = testDeployConfig(
FIXED_RATE
FIXED_RATE,
POSITION_DURATION
);
// Required to support ERC4626, since the test config initialSharePrice is wrong
config.baseToken = underlyingToken;
Expand Down
2 changes: 1 addition & 1 deletion test/integrations/HyperdriveFactory.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ contract HyperdriveFactoryBaseTest is HyperdriveTest {
minimumTransactionAmount: 1e15,
positionDuration: 365 days,
checkpointDuration: 1 days,
timeStretch: HyperdriveUtils.calculateTimeStretch(APR),
timeStretch: HyperdriveUtils.calculateTimeStretch(APR, 365 days),
governance: alice,
feeCollector: bob,
fees: IHyperdrive.Fees(0, 0, 0, 0),
Expand Down
3 changes: 2 additions & 1 deletion test/integrations/UsdcERC4626.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,8 @@ contract UsdcERC4626 is ERC4626ValidationTest {

// Config changes required to support ERC4626 with the correct initial share price.
IHyperdrive.PoolDeployConfig memory config = testDeployConfig(
FIXED_RATE
FIXED_RATE,
POSITION_DURATION
);
config.baseToken = underlyingToken;
config.minimumTransactionAmount = 1e6;
Expand Down
5 changes: 4 additions & 1 deletion test/integrations/hyperdrive/LPWithdrawalTest.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,10 @@ contract LPWithdrawalTest is HyperdriveTest {
super.setUp();

// Deploy a Hyperdrive pool with the standard config and a 5% APR.
IHyperdrive.PoolConfig memory config = testConfig(0.05e18);
IHyperdrive.PoolConfig memory config = testConfig(
0.05e18,
POSITION_DURATION
);
deploy(deployer, config);
}

Expand Down
55 changes: 44 additions & 11 deletions test/integrations/hyperdrive/NonstandardDecimals.sol
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,21 @@ contract NonstandardDecimalsTest is HyperdriveTest {

// Deploy the pool with a small minimum share reserves since we're
// using nonstandard decimals in this suite.
IHyperdrive.PoolConfig memory config = testConfig(0.05e18);
IHyperdrive.PoolConfig memory config = testConfig(
0.05e18,
POSITION_DURATION
);
config.minimumShareReserves = 1e6;
config.minimumTransactionAmount = 1e6;
deploy(deployer, config);
}

function test_nonstandard_decimals_symmetry() external {
// Deploy and initialize the pool.
IHyperdrive.PoolConfig memory config = testConfig(1e18);
IHyperdrive.PoolConfig memory config = testConfig(
1e18,
POSITION_DURATION
);
config.initialSharePrice = 0.7348e18;
config.minimumShareReserves = 1e6;
config.minimumTransactionAmount = 1e6;
Expand All @@ -53,7 +59,10 @@ contract NonstandardDecimalsTest is HyperdriveTest {

function test_nonstandard_decimals_longs_outstanding() external {
// Deploy and initialize the pool.
IHyperdrive.PoolConfig memory config = testConfig(0.02e18);
IHyperdrive.PoolConfig memory config = testConfig(
0.02e18,
POSITION_DURATION
);
config.minimumShareReserves = 1e6;
config.minimumTransactionAmount = 1e6;
deploy(deployer, config);
Expand Down Expand Up @@ -83,7 +92,10 @@ contract NonstandardDecimalsTest is HyperdriveTest {

function test_nonstandard_decimals_shorts_outstanding() external {
// Deploy and initialize the pool.
IHyperdrive.PoolConfig memory config = testConfig(0.02e18);
IHyperdrive.PoolConfig memory config = testConfig(
0.02e18,
POSITION_DURATION
);
config.minimumShareReserves = 1e6;
config.minimumTransactionAmount = 1e6;
deploy(deployer, config);
Expand Down Expand Up @@ -144,7 +156,10 @@ contract NonstandardDecimalsTest is HyperdriveTest {
// essentially all of his capital back.
{
// Deploy and initialize the pool.
IHyperdrive.PoolConfig memory config = testConfig(0.02e18);
IHyperdrive.PoolConfig memory config = testConfig(
0.02e18,
POSITION_DURATION
);
config.minimumShareReserves = 1e6;
config.minimumTransactionAmount = 1e6;
deploy(deployer, config);
Expand All @@ -165,7 +180,10 @@ contract NonstandardDecimalsTest is HyperdriveTest {
// duration. He should receive the base he paid plus fixed interest.
{
// Deploy and initialize the pool.
IHyperdrive.PoolConfig memory config = testConfig(0.02e18);
IHyperdrive.PoolConfig memory config = testConfig(
0.02e18,
POSITION_DURATION
);
config.minimumShareReserves = 1e6;
config.minimumTransactionAmount = 1e6;
deploy(deployer, config);
Expand Down Expand Up @@ -199,7 +217,10 @@ contract NonstandardDecimalsTest is HyperdriveTest {
// value of the bonds.
{
// Deploy and initialize the pool.
IHyperdrive.PoolConfig memory config = testConfig(0.02e18);
IHyperdrive.PoolConfig memory config = testConfig(
0.02e18,
POSITION_DURATION
);
config.minimumShareReserves = 1e6;
config.minimumTransactionAmount = 1e6;
deploy(deployer, config);
Expand Down Expand Up @@ -241,7 +262,10 @@ contract NonstandardDecimalsTest is HyperdriveTest {
// essentially all of his capital back.
{
// Deploy and initialize the pool.
IHyperdrive.PoolConfig memory config = testConfig(0.02e18);
IHyperdrive.PoolConfig memory config = testConfig(
0.02e18,
POSITION_DURATION
);
config.minimumShareReserves = 1e6;
config.minimumTransactionAmount = 1e6;
deploy(deployer, config);
Expand All @@ -263,7 +287,10 @@ contract NonstandardDecimalsTest is HyperdriveTest {
// interest minus the fixed interest.
{
// Deploy and initialize the pool.
IHyperdrive.PoolConfig memory config = testConfig(0.02e18);
IHyperdrive.PoolConfig memory config = testConfig(
0.02e18,
POSITION_DURATION
);
config.minimumShareReserves = 1e6;
config.minimumTransactionAmount = 1e6;
deploy(deployer, config);
Expand Down Expand Up @@ -303,7 +330,10 @@ contract NonstandardDecimalsTest is HyperdriveTest {
// variable interest earned by the short.
{
// Deploy and initialize the pool.
IHyperdrive.PoolConfig memory config = testConfig(0.02e18);
IHyperdrive.PoolConfig memory config = testConfig(
0.02e18,
POSITION_DURATION
);
config.minimumShareReserves = 1e6;
config.minimumTransactionAmount = 1e6;
deploy(deployer, config);
Expand Down Expand Up @@ -385,7 +415,10 @@ contract NonstandardDecimalsTest is HyperdriveTest {
uint256 shortAmount
) internal {
// Redeploy the pool so that the edge cases function can call it repeatedly.
IHyperdrive.PoolConfig memory config = testConfig(0.05e18);
IHyperdrive.PoolConfig memory config = testConfig(
0.05e18,
POSITION_DURATION
);
config.minimumShareReserves = 1e6;
config.minimumTransactionAmount = 1e6;
deploy(deployer, config);
Expand Down
10 changes: 8 additions & 2 deletions test/integrations/hyperdrive/ReentrancyTest.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,10 @@ contract ReentrancyTest is HyperdriveTest {
vm.startPrank(deployer);
tester = new ReentrantERC20();
baseToken = ERC20Mintable(address(tester));
IHyperdrive.PoolConfig memory config = testConfig(0.05e18);
IHyperdrive.PoolConfig memory config = testConfig(
0.05e18,
POSITION_DURATION
);
config.baseToken = IERC20(address(baseToken));
deploy(deployer, config);
}
Expand All @@ -263,7 +266,10 @@ contract ReentrancyTest is HyperdriveTest {
tester = new ReentrantEthReceiver();
vm.deal(address(tester), 10_000e18);
baseToken = ERC20Mintable(address(ETH));
IHyperdrive.PoolConfig memory config = testConfig(0.05e18);
IHyperdrive.PoolConfig memory config = testConfig(
0.05e18,
POSITION_DURATION
);
config.baseToken = IERC20(address(ETH));
deploy(deployer, config);
}
Expand Down
5 changes: 4 additions & 1 deletion test/integrations/hyperdrive/SandwichTest.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,10 @@ contract SandwichTest is HyperdriveTest {
uint256 tradeAmount,
uint256 sandwichAmount
) external {
IHyperdrive.PoolConfig memory config = testConfig(0.05e18);
IHyperdrive.PoolConfig memory config = testConfig(
0.05e18,
POSITION_DURATION
);
deploy(alice, config);
fixedRate = fixedRate.normalizeToRange(0.001e18, 1e18);
contribution = contribution.normalizeToRange(1_000e18, 500_000_000e18);
Expand Down
5 changes: 4 additions & 1 deletion test/units/ForceRevertDelegatecall.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,10 @@ contract DummyHyperdrive is Hyperdrive, MockHyperdriveBase {
minimumTransactionAmount: 1e15,
positionDuration: 365 days,
checkpointDuration: 1 days,
timeStretch: HyperdriveUtils.calculateTimeStretch(0.05e18),
timeStretch: HyperdriveUtils.calculateTimeStretch(
0.05e18,
365 days
),
governance: address(0),
feeCollector: address(0),
fees: IHyperdrive.Fees({
Expand Down
9 changes: 6 additions & 3 deletions test/units/hyperdrive/CloseLongTest.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -684,7 +684,10 @@ contract CloseLongTest is HyperdriveTest {
uint256 contribution = 500_000_000e18;

// 1. Deploy a pool with zero fees
IHyperdrive.PoolConfig memory config = testConfig(fixedRate);
IHyperdrive.PoolConfig memory config = testConfig(
fixedRate,
POSITION_DURATION
);
deploy(address(deployer), config);
// Initialize the pool with a large amount of capital.
initialize(alice, fixedRate, contribution);
Expand All @@ -701,7 +704,7 @@ contract CloseLongTest is HyperdriveTest {
// 4. deploy a pool with 100% curve fees and 100% gov fees (this is nice bc
// it ensures that all the fees are credited to governance and thus subtracted
// from the shareReserves
config = testConfig(fixedRate);
config = testConfig(fixedRate, POSITION_DURATION);
config.fees = IHyperdrive.Fees({
curve: 0,
flat: 0.01e18,
Expand All @@ -725,7 +728,7 @@ contract CloseLongTest is HyperdriveTest {
assert(govFees > 1e5);

// 7. deploy a pool with 100% curve fees and 0% gov fees
config = testConfig(fixedRate);
config = testConfig(fixedRate, POSITION_DURATION);
config.fees = IHyperdrive.Fees({
curve: 0,
flat: 0.01e18,
Expand Down
16 changes: 11 additions & 5 deletions test/units/hyperdrive/CloseShortTest.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -482,7 +482,10 @@ contract CloseShortTest is HyperdriveTest {
uint256 contribution = 500_000_000e18;

// 1. Deploy a pool with zero fees
IHyperdrive.PoolConfig memory config = testConfig(fixedRate);
IHyperdrive.PoolConfig memory config = testConfig(
fixedRate,
POSITION_DURATION
);
deploy(address(deployer), config);
// Initialize the pool with a large amount of capital.
initialize(alice, fixedRate, contribution);
Expand All @@ -499,7 +502,7 @@ contract CloseShortTest is HyperdriveTest {
// 4. deploy a pool with 100% curve fees and 100% gov fees (this is nice bc
// it ensures that all the fees are credited to governance and thus subtracted
// from the shareReserves
config = testConfig(fixedRate);
config = testConfig(fixedRate, POSITION_DURATION);
config.fees = IHyperdrive.Fees({
curve: 0,
flat: 1e18,
Expand Down Expand Up @@ -534,7 +537,7 @@ contract CloseShortTest is HyperdriveTest {
assert(govFees > 1e5);

// 7. deploy a pool with 100% curve fees and 0% gov fees
config = testConfig(fixedRate);
config = testConfig(fixedRate, POSITION_DURATION);
config.fees = IHyperdrive.Fees({
curve: 0,
flat: 1e18,
Expand Down Expand Up @@ -579,7 +582,10 @@ contract CloseShortTest is HyperdriveTest {
uint256 maturityTime;

// Initialize a pool with no flat fee as a baseline
IHyperdrive.PoolConfig memory config = testConfig(fixedRate);
IHyperdrive.PoolConfig memory config = testConfig(
fixedRate,
POSITION_DURATION
);
config.fees = IHyperdrive.Fees({
curve: 0,
flat: 0,
Expand Down Expand Up @@ -613,7 +619,7 @@ contract CloseShortTest is HyperdriveTest {
IHyperdrive.MarketState memory noFlatFee = hyperdrive.getMarketState();

// Configure a pool with a 100% flatFee
config = testConfig(fixedRate);
config = testConfig(fixedRate, POSITION_DURATION);
config.fees = IHyperdrive.Fees({
curve: 0,
flat: 1e18,
Expand Down
Loading

0 comments on commit f4aeeee

Please sign in to comment.