Skip to content

Commit

Permalink
CDAuctioneer: finish implementation and tests for adjusting the tick …
Browse files Browse the repository at this point in the history
…size after target achievement
  • Loading branch information
0xJem committed Jan 9, 2025
1 parent 4071fc8 commit 135ffed
Show file tree
Hide file tree
Showing 3 changed files with 246 additions and 68 deletions.
13 changes: 8 additions & 5 deletions src/policies/CDAuctioneer.sol
Original file line number Diff line number Diff line change
Expand Up @@ -225,8 +225,6 @@ contract CDAuctioneer is IConvertibleDepositAuctioneer, Policy, RolesConsumer, R

// Cycle through the ticks until the deposit is fully converted
while (remainingDeposit > 0) {
// TODO what if the target is reached?

uint256 depositAmount = remainingDeposit;
uint256 convertibleAmount = _getConvertedDeposit(remainingDeposit, updatedTickPrice);

Expand Down Expand Up @@ -333,6 +331,7 @@ contract CDAuctioneer is IConvertibleDepositAuctioneer, Policy, RolesConsumer, R
///
/// It uses the following approach:
/// - Calculate the added capacity based on the time passed since the last bid, and add it to the current capacity to get the new capacity
/// - If the calculation is occurring on a new day, the tick size will reset to the standard
/// - Until the new capacity is <= to the tick size, reduce the capacity by the tick size and reduce the price by the tick step
/// - If the calculated price is ever lower than the minimum price, the new price is set to the minimum price and the capacity is set to the tick size
function getCurrentTick() public view onlyActive returns (Tick memory tick) {
Expand All @@ -346,11 +345,15 @@ contract CDAuctioneer is IConvertibleDepositAuctioneer, Policy, RolesConsumer, R
tick = _previousTick;
uint256 newCapacity = tick.capacity + capacityToAdd;

// If the current date is on a different day to the last bid, the tick size will reset to the standard
if (block.timestamp / 86400 > _previousTick.lastUpdate / 86400)
tick.tickSize = _auctionParameters.tickSize;

// Iterate over the ticks until the capacity is within the tick size
// This is the opposite of what happens in the bid function
while (newCapacity > _auctionParameters.tickSize) {
while (newCapacity > tick.tickSize) {
// Reduce the capacity by the tick size
newCapacity -= _auctionParameters.tickSize;
newCapacity -= tick.tickSize;

// Adjust the tick price by the tick step, in the opposite direction to the bid function
tick.price = tick.price.mulDivUp(ONE_HUNDRED_PERCENT, _tickStep);
Expand All @@ -359,7 +362,7 @@ contract CDAuctioneer is IConvertibleDepositAuctioneer, Policy, RolesConsumer, R
// Tick capacity is full if the min price is exceeded
if (tick.price < _auctionParameters.minPrice) {
tick.price = _auctionParameters.minPrice;
newCapacity = _auctionParameters.tickSize;
newCapacity = tick.tickSize;
break;
}
}
Expand Down
85 changes: 39 additions & 46 deletions src/test/policies/ConvertibleDepositAuctioneer/bid.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ import {FullMath} from "src/libraries/FullMath.sol";
import {IConvertibleDepositAuctioneer} from "src/policies/interfaces/IConvertibleDepositAuctioneer.sol";
import {CDPOSv1} from "src/modules/CDPOS/CDPOS.v1.sol";

import {console2} from "forge-std/console2.sol";

contract ConvertibleDepositAuctioneerBidTest is ConvertibleDepositAuctioneerTest {
function _assertConvertibleDepositPosition(
uint256 bidAmount_,
Expand Down Expand Up @@ -703,25 +701,25 @@ contract ConvertibleDepositAuctioneerBidTest is ConvertibleDepositAuctioneerTest
// Tick two: 10e9, price is 165e17, max bid amount is 165e18
// Tick three: 5e9, price is 1815e16, max bid amount is 9075e16
// Total bid amount = 150e18 + 165e18 + 9075e16 = 40575e16
uint256 reserveTokenBalance = 150e18 + 165e18 + 9075e16;
uint256 bidAmount = bound(bidAmount_, 315e18, reserveTokenBalance - 1);
uint256 bidOneAmount = 150e18;
uint256 bidTwoAmount = 165e18;
uint256 bidThreeMaxAmount = 9075e16;
uint256 reserveTokenBalance = bidOneAmount + bidTwoAmount + bidThreeMaxAmount;
uint256 bidAmount = bound(bidAmount_, bidOneAmount + bidTwoAmount, reserveTokenBalance - 1);
uint256 tickThreePrice = 1815e16;
uint256 tickThreeBidAmount = bidAmount - bidOneAmount - bidTwoAmount;

uint256 tickOneConvertedAmount = (150e18 * 1e9) / 15e18;
uint256 tickTwoConvertedAmount = (165e18 * 1e9) / 165e17;
uint256 tickThreeConvertedAmount = ((bidAmount - 150e18 - 165e18) * 1e9) / tickThreePrice;
uint256 tickOneConvertedAmount = (bidOneAmount * 1e9) / 15e18;
uint256 tickTwoConvertedAmount = (bidTwoAmount * 1e9) / 165e17;
uint256 tickThreeConvertedAmount = (tickThreeBidAmount * 1e9) / tickThreePrice;
uint256 expectedConvertedAmount = tickOneConvertedAmount +
tickTwoConvertedAmount +
tickThreeConvertedAmount;

console2.log("tickOneConvertedAmount", tickOneConvertedAmount);
console2.log("tickTwoConvertedAmount", tickTwoConvertedAmount);
console2.log("tickThreeConvertedAmount", tickThreeConvertedAmount);

// Recalculate the bid amount, in case tickThreeConvertedAmount is 0
uint256 expectedDepositIn = 150e18 + 165e18 + tickThreeConvertedAmount * tickThreePrice / 1e9;
console2.log("expectedDepositIn", expectedDepositIn);
console2.log("tick three deposit", tickThreeConvertedAmount * tickThreePrice / 1e9);
uint256 expectedDepositIn = bidOneAmount +
bidTwoAmount +
(tickThreeConvertedAmount == 0 ? 0 : tickThreeBidAmount);

// Check preview
(uint256 previewOhmOut, ) = auctioneer.previewBid(bidAmount);
Expand Down Expand Up @@ -765,44 +763,39 @@ contract ConvertibleDepositAuctioneerBidTest is ConvertibleDepositAuctioneerTest
)
public
givenInitialized
givenAddressHasReserveToken(recipient, 795064875e12)
givenReserveTokenSpendingIsApproved(recipient, address(convertibleDepository), 795064875e12)
givenAddressHasReserveToken(recipient, 796064875e12)
givenReserveTokenSpendingIsApproved(recipient, address(convertibleDepository), 796064875e12)
{
// We want the converted amount to be >= 2 * day target, 40e9
// Tick one: 10e9, price is 15e18, max bid amount is 150e18
// Tick two: 10e9, price is 165e17, max bid amount is 165e18
// Tick three: 5e9, price is 1815e16, max bid amount is 9075e16
// Tick four: 5e9, price is 19965e15, max bid amount is 99825e15
// Tick five: 5e9, price is 219615e14, max bid amount is 1098075e14
// Tick six: 5e9, price is 2395765e13, max bid amount is 11978825e13
// Tick seven: 2.5e9, price is 25954315e12, max bid amount is 59894125e12
// Total bid amount = 150e18 + 165e18 + 9075e16 + 99825e15 + 1098075e14 + 11978825e13 + 59894125e12 = 795064875e12
uint256 reserveTokenBalance = 795064875e12;
uint256 bidAmount = bound(bidAmount_, 73517075e13, reserveTokenBalance - 1);
// Tick six: 5e9, price is 2415765e13, max bid amount is 12078825e13
// Tick seven: 2.5e9, price is 26573415e12, max bid amount is 59894125e12
// Max bid amount = 150e18 + 165e18 + 9075e16 + 99825e15 + 1098075e14 + 12078825e13 + 59894125e12 = 796064875e12
// Ticks one to six bid amount = 150e18 + 165e18 + 9075e16 + 99825e15 + 1098075e14 + 12078825e13 = 73617075e13
uint256 reserveTokenBalance = 796064875e12;
uint256 bidAmount = bound(bidAmount_, 73617075e13, reserveTokenBalance - 1);

uint256 expectedConvertedAmount;
uint256 expectedDepositIn;
{
uint256 tickOneConvertedAmount = (150e18 * 1e9) / 15e18;
uint256 tickTwoConvertedAmount = (165e18 * 1e9) / 165e17;
uint256 tickThreeConvertedAmount = (9075e16 * 1e9) / 1815e16;
uint256 tickFourConvertedAmount = (99825e15 * 1e9) / 19965e15;
uint256 tickFiveConvertedAmount = (1098075e14 * 1e9) / 219615e14;
uint256 tickSixConvertedAmount = (11978825e13 * 1e9) / 2395765e13;
uint256 tickSevenConvertedAmount = ((bidAmount -
150e18 -
165e18 -
9075e16 -
99825e15 -
1098075e14 -
11978825e13) * 1e9) / 25954315e12;
expectedConvertedAmount =
tickOneConvertedAmount +
tickTwoConvertedAmount +
tickThreeConvertedAmount +
tickFourConvertedAmount +
tickFiveConvertedAmount +
tickSixConvertedAmount +
tickSevenConvertedAmount;
// Tick one: 150e18 * 1e9 / 15e18 = 10e9
// Tick two: 165e18 * 1e9 / 165e17 = 10e9
// Tick three: 9075e16 * 1e9 / 1815e16 = 5e9
// Tick four: 99825e15 * 1e9 / 19965e15 = 5e9
// Tick five: 1098075e14 * 1e9 / 219615e14 = 5e9
// Tick six: 12078825e23 * 1e9 / 2395765e13 = 5e9
uint256 ticksOneToSixConvertedAmount = 40e9;
uint256 tickSevenConvertedAmount = ((bidAmount - 73617075e13) * 1e9) / 26573415e12;
expectedConvertedAmount = ticksOneToSixConvertedAmount + tickSevenConvertedAmount;

// Recalculate the bid amount, in case tickSevenConvertedAmount is 0
expectedDepositIn =
73617075e13 +
(tickSevenConvertedAmount == 0 ? 0 : (bidAmount - 73617075e13));
}

// Check preview
Expand All @@ -817,17 +810,17 @@ contract ConvertibleDepositAuctioneerBidTest is ConvertibleDepositAuctioneerTest

// Assert returned values
_assertConvertibleDepositPosition(
bidAmount,
expectedDepositIn,
expectedConvertedAmount,
reserveTokenBalance - bidAmount,
reserveTokenBalance - expectedDepositIn,
0,
0,
ohmOut,
positionId
);

// Assert the day state
assertEq(auctioneer.getDayState().deposits, bidAmount, "day deposits");
assertEq(auctioneer.getDayState().deposits, expectedDepositIn, "day deposits");
assertEq(auctioneer.getDayState().convertible, expectedConvertedAmount, "day convertible");

// Assert the state
Expand All @@ -836,7 +829,7 @@ contract ConvertibleDepositAuctioneerBidTest is ConvertibleDepositAuctioneerTest
// Assert the tick
_assertPreviousTick(
10e9 + 10e9 + 5e9 + 5e9 + 5e9 + 5e9 + 25e8 - expectedConvertedAmount,
25954315e12,
26573415e12,
25e8, // The tick size is halved twice as the target is met or exceeded twice
uint48(block.timestamp)
);
Expand Down
Loading

0 comments on commit 135ffed

Please sign in to comment.