Skip to content

Commit

Permalink
fix: adjust quoteAmountToSwapBeforeRebalance for custom shares.
Browse files Browse the repository at this point in the history
  • Loading branch information
clement-ux committed Sep 16, 2024
1 parent 6b72dc9 commit 944bb28
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 19 deletions.
4 changes: 4 additions & 0 deletions contracts/contracts/interfaces/aerodrome/IAMOStrategy.sol
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,8 @@ interface IAMOStrategy {
function allowedWethShareStart() external view returns (uint256);

function allowedWethShareEnd() external view returns (uint256);

function claimGovernance() external;

function transferGovernance(address _governor) external;
}
31 changes: 30 additions & 1 deletion contracts/contracts/utils/AerodromeAMOQuoter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ contract QuoterHelper {
IQuoterV2 public quoterV2;
IAMOStrategy public strategy;

address public originalGovernor;

////////////////////////////////////////////////////////////////
/// --- ERRORS & EVENTS
////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -321,7 +323,13 @@ contract QuoterHelper {
uint160 currentPrice = strategy.getPoolX96Price();
uint160 ticker0Price = strategy.sqrtRatioX96TickLower();
uint160 ticker1Price = strategy.sqrtRatioX96TickHigher();
uint160 targetPrice = (ticker0Price * 20 + ticker1Price * 80) / 100;
uint256 allowedWethShareStart = strategy.allowedWethShareStart();
uint256 allowedWethShareEnd = strategy.allowedWethShareEnd();
uint160 mid = uint160(allowedWethShareStart + allowedWethShareEnd) / 2;
uint160 targetPrice = (ticker0Price *
mid +
ticker1Price *
(1 ether - mid)) / 1 ether;

return currentPrice > targetPrice;
}
Expand Down Expand Up @@ -415,6 +423,19 @@ contract QuoterHelper {
uint160 currentPrice = strategy.getPoolX96Price();
return currentPrice > sqrtPriceTargetX96;
}

function claimGovernanceOnAMO() public {
originalGovernor = strategy.governor();
strategy.claimGovernance();
}

function giveBackGovernanceOnAMO() public {
require(
originalGovernor != address(0),
"Quoter: Original governor not set"
);
strategy.transferGovernance(originalGovernor);
}
}

/// @title AerodromeAMOQuoter
Expand Down Expand Up @@ -552,4 +573,12 @@ contract AerodromeAMOQuoter {
sqrtPriceAfterX96
);
}

function claimGovernance() public {
quoterHelper.claimGovernanceOnAMO();
}

function giveBackGovernance() public {
quoterHelper.giveBackGovernanceOnAMO();
}
}
69 changes: 51 additions & 18 deletions contracts/test/strategies/aerodrome-amo.base.fork-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -613,7 +613,10 @@ describe("ForkTest: Aerodrome AMO Strategy (Base)", function () {
it("Should be able to deposit to the pool & rebalance", async () => {
await mintAndDepositToStrategy({ amount: oethUnits("5") });

const { value, direction } = await quoteAmountToSwapBeforeRebalance();
const { value, direction } = await quoteAmountToSwapBeforeRebalance({
lowValue: oethUnits("0"),
highValue: oethUnits("0"),
});
const tx = await rebalance(value, direction, value.mul("99").div("100"));

await expect(tx).to.emit(aerodromeAmoStrategy, "PoolRebalanced");
Expand All @@ -623,7 +626,10 @@ describe("ForkTest: Aerodrome AMO Strategy (Base)", function () {
it("Should be able to deposit to the pool & rebalance multiple times", async () => {
await mintAndDepositToStrategy({ amount: oethUnits("5") });

const { value, direction } = await quoteAmountToSwapBeforeRebalance();
const { value, direction } = await quoteAmountToSwapBeforeRebalance({
lowValue: oethUnits("0"),
highValue: oethUnits("0"),
});
const tx = await rebalance(value, direction, value.mul("99").div("100"));

await expect(tx).to.emit(aerodromeAmoStrategy, "PoolRebalanced");
Expand Down Expand Up @@ -690,11 +696,14 @@ describe("ForkTest: Aerodrome AMO Strategy (Base)", function () {
});

it("Should revert when pool rebalance is off target", async () => {
const { value, direction } = await quoteAmountToSwapBeforeRebalance();
const { value, direction } = await quoteAmountToSwapBeforeRebalance({
lowValue: oethUnits("0.90"),
highValue: oethUnits("0.92"),
});

await expect(
rebalance(value.mul("200").div("100"), direction, 0)
).to.be.revertedWith("PoolRebalanceOutOfBounds");
await expect(rebalance(value, direction, 0)).to.be.revertedWith(
"PoolRebalanceOutOfBounds"
);
});

it("Should be able to rebalance the pool when price pushed to 1:1", async () => {
Expand All @@ -709,7 +718,10 @@ describe("ForkTest: Aerodrome AMO Strategy (Base)", function () {
// supply some WETH for the rebalance
await mintAndDepositToStrategy({ amount: oethUnits("1") });

const { value, direction } = await quoteAmountToSwapBeforeRebalance();
const { value, direction } = await quoteAmountToSwapBeforeRebalance({
lowValue: oethUnits("0"),
highValue: oethUnits("0"),
});
await rebalance(value, direction, value.mul("99").div("100"));

await assetLpStakedInGauge();
Expand All @@ -725,7 +737,10 @@ describe("ForkTest: Aerodrome AMO Strategy (Base)", function () {
swapWeth: direction0,
});

const { value, direction } = await quoteAmountToSwapBeforeRebalance();
const { value, direction } = await quoteAmountToSwapBeforeRebalance({
lowValue: oethUnits("0"),
highValue: oethUnits("0"),
});
await rebalance(value, direction, value.mul("99").div("100"));

await assetLpStakedInGauge();
Expand Down Expand Up @@ -878,7 +893,10 @@ describe("ForkTest: Aerodrome AMO Strategy (Base)", function () {
const setup = async () => {
await mintAndDepositToStrategy({ amount: oethUnits("5") });

const { value, direction } = await quoteAmountToSwapBeforeRebalance();
const { value, direction } = await quoteAmountToSwapBeforeRebalance({
lowValue: oethUnits("0"),
highValue: oethUnits("0"),
});

// move the price to pre-configured 20% value
await rebalance(
Expand Down Expand Up @@ -955,26 +973,41 @@ describe("ForkTest: Aerodrome AMO Strategy (Base)", function () {
});
};

const quoteAmountToSwapBeforeRebalance = async () => {
// Get the strategist address
const strategist = oethbVault.strategistAddr();

const quoteAmountToSwapBeforeRebalance = async ({ lowValue, highValue }) => {
// Set Quoter as strategist to pass the `onlyGovernorOrStrategist` requirement
await oethbVault
.connect(await impersonateAndFund(addresses.base.governor))
.setStrategistAddr(await quoter.quoterHelper());

// Get governor
const gov = await aerodromeAmoStrategy.governor();
// Set pending governance to quoter helper
await aerodromeAmoStrategy
.connect(await impersonateAndFund(gov))
.transferGovernance(await quoter.quoterHelper());
// Quoter claim governance)
await quoter.claimGovernance();

let txResponse;
if (lowValue == 0 && highValue == 0) {
txResponse = await quoter["quoteAmountToSwapBeforeRebalance()"]();
} else {
txResponse = await quoter[
"quoteAmountToSwapBeforeRebalance(uint256,uint256)"
](lowValue, highValue);
}
// Get the quote
const txResponse = await quoter["quoteAmountToSwapBeforeRebalance()"]();
const txReceipt = await txResponse.wait();
const [transferEvent] = txReceipt.events;
const value = transferEvent.args.value;
const direction = transferEvent.args.swapWETHForOETHB;

// Set back the original strategist
/*
await oethbVault
.connect(await impersonateAndFund(addresses.base.governor))
.setStrategistAddr(strategist);
*/
quoter.giveBackGovernance();
await aerodromeAmoStrategy
.connect(await impersonateAndFund(gov))
.claimGovernance();

// Return the value and direction
return { value, direction };
Expand Down

0 comments on commit 944bb28

Please sign in to comment.