Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gradual Dutch Auction Module #177

Open
wants to merge 71 commits into
base: develop
Choose a base branch
from
Open
Changes from 1 commit
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
2df6a18
forge install: prb-math
Oighty Apr 30, 2024
aa3fa81
git: use modified prb-math
Oighty May 1, 2024
f8fa62f
chore: update install script
Oighty May 1, 2024
6025353
feat: initial GDA implementation
Oighty May 1, 2024
bf170a7
fix: minor GDA updates and add'l TODOs
Oighty May 1, 2024
ef82640
fix: change gda timestamps to be uint256
Oighty May 1, 2024
43ddff1
Remove prb-math submodule
0xJem May 1, 2024
7208c4b
Re-add prb-math
0xJem May 1, 2024
3c75f34
If the deployed address of a required contract (UniV2/V3 factory, GUn…
0xJem May 1, 2024
19bd856
chore: linting
0xJem May 1, 2024
bb3b8de
Add forge test config into foundry.toml
0xJem May 1, 2024
81ab2bc
feat: handle positive and negative T in GDA
Oighty May 1, 2024
ad504e9
refactor: simplify gda inputs and add some bounds
Oighty May 1, 2024
e140c16
fix: compile error
Oighty May 2, 2024
c71aeb2
fix: use constant bounds for GDA and rename target
Oighty May 2, 2024
b4c65a5
fix: convert times to fixed point days in GDA and add bounds
Oighty May 2, 2024
79375d6
chore: remove previously added constant and clarify docs
Oighty May 2, 2024
fe594b3
chore: switch out solady for prb-math in GDA
Oighty May 2, 2024
57c69e7
feat: avoid overflows and clean-up TODOs
Oighty May 8, 2024
c916291
chore: only one math lib in GDA
Oighty May 15, 2024
68bf9fa
test: add GDA test base contract
Oighty May 15, 2024
b0e0c96
fix: remove extra checks and update min decay period
Oighty May 21, 2024
a464b8e
fix: divide decay constant seconds by one day
Oighty May 21, 2024
212da97
test: wip on create auction tests for GDA
Oighty May 21, 2024
a05403f
test: finish GDA create auction tests
Oighty May 22, 2024
e9e1c6f
Merge branch 'fixed-batch' into gda-new
Oighty May 22, 2024
954de7a
refactor: add GDA interface and fix test compile
Oighty May 22, 2024
24d04a6
chore: update test salts
Oighty May 22, 2024
f26456d
test: GDA priceFor tests
Oighty May 22, 2024
d5ca25f
test: more priceFor test updates
Oighty May 22, 2024
6ef438d
fix: gda price equations, includes temp logging
Oighty May 23, 2024
a127c22
test: wip GDA payoutFor tests
Oighty May 23, 2024
3b0ddad
fix: add'l validation and temp logging in GDA
Oighty May 23, 2024
ab575b7
test: add'l GDA tests, still some TODOs
Oighty May 24, 2024
bee920c
chore: update prb-math dependency
Oighty May 24, 2024
b52abc6
fix: reduce error correction based on library improvements
Oighty May 24, 2024
849f40c
fix: compile error in test
Oighty May 24, 2024
1492909
wip: more GDA error bounds
Oighty May 28, 2024
73744fe
fix: update and clarify decay constant + min price bounds
Oighty May 28, 2024
fa46470
test: update GDA create auction tests
Oighty May 28, 2024
2e3e463
test: max amount out GDA test updates
Oighty May 28, 2024
af65d5c
wip: GDA priceFor test updates
Oighty May 28, 2024
1371ddd
chore: remove default verbosity from foundry config
Oighty May 28, 2024
1b0fba9
chore: lint
Oighty May 28, 2024
70a9655
test: GDA test improvements, most passing
Oighty May 29, 2024
83498e2
fix: priceFor rounding behavior
Oighty Sep 17, 2024
c7d754c
test: update failing GDA payoutFor and priceFor tests
Oighty Sep 17, 2024
8f86132
Merge branch 'develop' into gda-new
Oighty Sep 17, 2024
421c131
chore: lint
Oighty Sep 17, 2024
0fbc3cb
chore: fix remapping and compile issues
Oighty Sep 17, 2024
fb9a252
chore: lint
Oighty Sep 17, 2024
ffa9761
chore: soldeer updates
Oighty Sep 19, 2024
cc1c3b9
chore: remove submodule dep
Oighty Sep 19, 2024
18ded86
chore: update GDA deps
Oighty Sep 19, 2024
e9dc8d4
chore: lint (new forge fmt)
Oighty Sep 19, 2024
a47af6b
chore: minor cleanup
Oighty Sep 19, 2024
40a9d88
test: gda test updates to catch edge cases
Oighty Sep 19, 2024
a4781f5
test: update test salts
Oighty Sep 19, 2024
d8109fd
NatSpec for error
0xJem Sep 24, 2024
cad6b71
Cleanup
0xJem Sep 24, 2024
43338b8
Improve NatSpec output
0xJem Sep 24, 2024
131581e
Typos
0xJem Sep 25, 2024
b471433
Test TODOs
0xJem Sep 25, 2024
858a216
Additional test coverage
0xJem Sep 26, 2024
3c08fdf
Update soldeer.lock
0xJem Sep 26, 2024
8a91bec
Additional fuzz tests
0xJem Sep 26, 2024
fe5037d
chore: linting
0xJem Sep 26, 2024
c9f4790
Decimal tests
0xJem Sep 27, 2024
7e2b780
Attempt at pre-calculated tests
0xJem Sep 27, 2024
1f79e10
Amendments to calculations in tests
0xJem Sep 30, 2024
58eaf95
Adjustments to calculations. New test cases for days 1 and 2.
0xJem Sep 30, 2024
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
Prev Previous commit
Next Next commit
chore: switch out solady for prb-math in GDA
  • Loading branch information
Oighty committed May 2, 2024
commit fe594b3cbff1ed5a6580e7172c6a6849f3016d93
24 changes: 14 additions & 10 deletions src/modules/auctions/GDA.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,12 @@ import {AtomicAuctionModule} from "src/modules/auctions/AtomicAuctionModule.sol"
import {
UD60x18, ud, convert, ZERO, UNIT, uUNIT, EXP_MAX_INPUT
} from "lib/prb-math/src/UD60x18.sol";
import "lib/prb-math/src/Common.sol" as PRBMath;
import {FixedPointMathLib} from "lib/solady/src/utils/FixedPointMathLib.sol";

/// @notice Continuous Gradual Dutch Auction (GDA) module with exponential decay and a minimum price.
contract GradualDutchAuction is AtomicAuctionModule {
using FixedPointMathLib for uint256;
using {PRBMath.mulDiv} for uint256;

/// @notice Auction pricing data
struct AuctionData {
Expand Down Expand Up @@ -108,9 +109,9 @@ contract GradualDutchAuction is AtomicAuctionModule {
UD60x18 decayConstant;
{
uint256 quoteTokenScale = 10 ** lot_.quoteTokenDecimals;
UD60x18 q0 = ud(params.equilibriumPrice.fullMulDiv(uUNIT, quoteTokenScale));
UD60x18 q0 = ud(params.equilibriumPrice.mulDiv(uUNIT, quoteTokenScale));
UD60x18 q1 = q0.mul(UNIT - ud(params.decayTarget)).div(UNIT);
UD60x18 qm = ud(params.minimumPrice.fullMulDiv(uUNIT, quoteTokenScale));
UD60x18 qm = ud(params.minimumPrice.mulDiv(uUNIT, quoteTokenScale));

// Check that q0 > q1 > qm
// This ensures that the operand for the logarithm is positive
Expand All @@ -136,7 +137,7 @@ contract GradualDutchAuction is AtomicAuctionModule {

// Calculate emissions rate as number of tokens released per day
UD60x18 emissionsRate =
ud(lot_.capacity.fullMulDiv(uUNIT, 10 ** lot_.baseTokenDecimals)).div(duration);
ud(lot_.capacity.mulDiv(uUNIT, 10 ** lot_.baseTokenDecimals)).div(duration);

// Store auction data
AuctionData storage data = auctionData[lotId_];
Expand Down Expand Up @@ -205,10 +206,13 @@ contract GradualDutchAuction is AtomicAuctionModule {
// Scale the result to 18 decimals
uint256 quoteTokenScale = 10 ** lot.quoteTokenDecimals;
UD60x18 priceDiff =
ud((auction.equilibriumPrice - auction.minimumPrice).fullMulDiv(uUNIT, quoteTokenScale));
ud((auction.equilibriumPrice - auction.minimumPrice).mulDiv(uUNIT, quoteTokenScale));

// Calculate the second numerator factor: e^((k*P)/r) - 1
// This cannot exceed the max exponential input due to the bounds imbosed on auction creation
// emissions rate = initial capacity / duration
// payout must be less then or equal to initial capacity
// therefore, the resulting exponent is at most decay constant * duration
UD60x18 ekpr = auction.decayConstant.mul(payout).div(auction.emissionsRate).exp().sub(UNIT);

// Handle cases of T being positive or negative
Expand Down Expand Up @@ -245,7 +249,7 @@ contract GradualDutchAuction is AtomicAuctionModule {
}

// Scale price back to quote token decimals
uint256 amount = result.intoUint256().fullMulDiv(quoteTokenScale, uUNIT);
uint256 amount = result.intoUint256().mulDiv(quoteTokenScale, uUNIT);

return amount;
}
Expand Down Expand Up @@ -286,10 +290,10 @@ contract GradualDutchAuction is AtomicAuctionModule {

// Get quote token scale and convert equilibrium price to 18 decimals
uint256 quoteTokenScale = 10 ** lot.quoteTokenDecimals;
UD60x18 q0 = ud(auction.equilibriumPrice.fullMulDiv(uUNIT, quoteTokenScale));
UD60x18 q0 = ud(auction.equilibriumPrice.mulDiv(uUNIT, quoteTokenScale));

// Scale amount to 18 decimals
UD60x18 amount = ud(amount_.fullMulDiv(uUNIT, quoteTokenScale));
UD60x18 amount = ud(amount_.mulDiv(uUNIT, quoteTokenScale));

// Factors are calculated in a certain order to avoid precision loss
UD60x18 payout;
Expand Down Expand Up @@ -330,7 +334,7 @@ contract GradualDutchAuction is AtomicAuctionModule {
{
// Check that the amount / minPrice is not greater than the max payout (i.e. remaining capacity)
uint256 minPrice = auction.minimumPrice;
uint256 payoutAtMinPrice = FixedPointMathLib.fullMulDiv(
uint256 payoutAtMinPrice = FixedPointMathLib.mulDiv(
amount_, 10 ** lotData[lotId_].baseTokenDecimals, minPrice
);
if (payoutAtMinPrice > maxPayout(lotId_)) {
Expand All @@ -340,7 +344,7 @@ contract GradualDutchAuction is AtomicAuctionModule {

// Convert minimum price to 18 decimals
// Can't overflow because quoteTokenScale <= uUNIT
UD60x18 qm = ud(auction.minimumPrice.fullMulDiv(uUNIT, quoteTokenScale));
UD60x18 qm = ud(auction.minimumPrice.mulDiv(uUNIT, quoteTokenScale));

// Calculate first term: (k * Q) / qm
UD60x18 f = auction.decayConstant.mul(amount).div(qm);
Expand Down