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

Optimize GDA code #46

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
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
66 changes: 38 additions & 28 deletions .gas-snapshot
Original file line number Diff line number Diff line change
@@ -1,35 +1,45 @@
ExponentialCurveTest:test_getBuyInfoExample() (gas: 9113)
ExponentialCurveTest:test_getBuyInfoWithoutFee(uint128,uint64,uint8) (runs: 256, μ: 996, ~: 523)
ExponentialCurveTest:test_getBuyInfoWithoutFee(uint128,uint64,uint8) (runs: 256, μ: 961, ~: 523)
ExponentialCurveTest:test_getSellInfoExample() (gas: 9052)
ExponentialCurveTest:test_getSellInfoWithoutFee(uint128,uint128,uint8) (runs: 256, μ: 1860, ~: 604)
ExponentialCurveTest:test_getSellInfoWithoutFee(uint128,uint128,uint8) (runs: 256, μ: 1892, ~: 604)
GDACurveTest:test_getBuyInfoExample() (gas: 315467)
GDACurveTest:test_getBuyInfoFuzz(uint48) (runs: 256, μ: 29500, ~: 29276)
GDACurveTest:test_getBuyInfoOverflow() (gas: 23490)
GDACurveTest:test_getBuyInfoTimeDecayTooLarge() (gas: 67767)
GDACurveTest:test_getBuyInfoWithFees() (gas: 69564)
GDACurveTest:test_getSellInfoExample() (gas: 316310)
GDACurveTest:test_getSellInfoFuzz(uint48) (runs: 256, μ: 30807, ~: 30583)
GDACurveTest:test_getSellInfoOverflow() (gas: 19706)
GDACurveTest:test_getSellInfoTimeBoostTooLarge() (gas: 69191)
GDACurveTest:test_getSellInfoWithFees() (gas: 70871)
LinearCurveTest:test_getBuyInfoExample() (gas: 8642)
LinearCurveTest:test_getBuyInfoWithoutFee(uint128,uint128,uint8) (runs: 256, μ: 7249, ~: 8819)
LinearCurveTest:test_getBuyInfoWithoutFee(uint128,uint128,uint8) (runs: 256, μ: 7432, ~: 8819)
LinearCurveTest:test_getSellInfoExample() (gas: 8503)
LinearCurveTest:test_getSellInfoWithoutFee(uint128,uint128,uint8) (runs: 256, μ: 7488, ~: 8927)
NoArbExponentialCurveEnumerableERC20Test:test_bondingCurveBuySellNoProfit(uint56,uint64,uint8) (runs: 256, μ: 832090, ~: 1257232)
NoArbExponentialCurveEnumerableERC20Test:test_bondingCurveSellBuyNoProfit(uint56,uint64,uint8) (runs: 256, μ: 832631, ~: 1246069)
NoArbExponentialCurveEnumerableETHTest:test_bondingCurveBuySellNoProfit(uint56,uint64,uint8) (runs: 256, μ: 306180, ~: 407907)
NoArbExponentialCurveEnumerableETHTest:test_bondingCurveSellBuyNoProfit(uint56,uint64,uint8) (runs: 256, μ: 287935, ~: 408372)
NoArbExponentialCurveMissingEnumerableERC20Test:test_bondingCurveBuySellNoProfit(uint56,uint64,uint8) (runs: 256, μ: 817319, ~: 1265233)
NoArbExponentialCurveMissingEnumerableERC20Test:test_bondingCurveSellBuyNoProfit(uint56,uint64,uint8) (runs: 256, μ: 771543, ~: 1215053)
NoArbExponentialCurveMissingEnumerableETHTest:test_bondingCurveBuySellNoProfit(uint56,uint64,uint8) (runs: 256, μ: 294752, ~: 415908)
NoArbExponentialCurveMissingEnumerableETHTest:test_bondingCurveSellBuyNoProfit(uint56,uint64,uint8) (runs: 256, μ: 250843, ~: 377356)
NoArbLinearCurveEnumerableERC20Test:test_bondingCurveBuySellNoProfit(uint56,uint64,uint8) (runs: 256, μ: 770471, ~: 1258953)
NoArbLinearCurveEnumerableERC20Test:test_bondingCurveSellBuyNoProfit(uint56,uint64,uint8) (runs: 256, μ: 843740, ~: 1247790)
NoArbLinearCurveEnumerableETHTest:test_bondingCurveBuySellNoProfit(uint56,uint64,uint8) (runs: 256, μ: 320801, ~: 409628)
NoArbLinearCurveEnumerableETHTest:test_bondingCurveSellBuyNoProfit(uint56,uint64,uint8) (runs: 256, μ: 300051, ~: 410093)
NoArbLinearCurveMissingEnumerableERC20Test:test_bondingCurveBuySellNoProfit(uint56,uint64,uint8) (runs: 256, μ: 865661, ~: 1266954)
NoArbLinearCurveMissingEnumerableERC20Test:test_bondingCurveSellBuyNoProfit(uint56,uint64,uint8) (runs: 256, μ: 761095, ~: 1216774)
NoArbLinearCurveMissingEnumerableETHTest:test_bondingCurveBuySellNoProfit(uint56,uint64,uint8) (runs: 256, μ: 291987, ~: 417629)
NoArbLinearCurveMissingEnumerableETHTest:test_bondingCurveSellBuyNoProfit(uint56,uint64,uint8) (runs: 256, μ: 252752, ~: 379077)
NoArbXykCurveEnumerableERC20Test:test_bondingCurveBuySellNoProfit(uint56,uint64,uint8) (runs: 256, μ: 805923, ~: 1259565)
NoArbXykCurveEnumerableERC20Test:test_bondingCurveSellBuyNoProfit(uint56,uint64,uint8) (runs: 256, μ: 801145, ~: 1248402)
NoArbXykCurveEnumerableETHTest:test_bondingCurveBuySellNoProfit(uint56,uint64,uint8) (runs: 256, μ: 324331, ~: 410240)
NoArbXykCurveEnumerableETHTest:test_bondingCurveSellBuyNoProfit(uint56,uint64,uint8) (runs: 256, μ: 309238, ~: 417713)
NoArbXykCurveMissingEnumerableERC20Test:test_bondingCurveBuySellNoProfit(uint56,uint64,uint8) (runs: 256, μ: 839653, ~: 1267566)
NoArbXykCurveMissingEnumerableERC20Test:test_bondingCurveSellBuyNoProfit(uint56,uint64,uint8) (runs: 256, μ: 797784, ~: 1217386)
NoArbXykCurveMissingEnumerableETHTest:test_bondingCurveBuySellNoProfit(uint56,uint64,uint8) (runs: 256, μ: 320663, ~: 418241)
NoArbXykCurveMissingEnumerableETHTest:test_bondingCurveSellBuyNoProfit(uint56,uint64,uint8) (runs: 256, μ: 284274, ~: 386697)
LinearCurveTest:test_getSellInfoWithoutFee(uint128,uint128,uint8) (runs: 256, μ: 7677, ~: 8927)
NoArbExponentialCurveEnumerableERC20Test:test_bondingCurveBuySellNoProfit(uint56,uint64,uint8) (runs: 256, μ: 787888, ~: 1257232)
NoArbExponentialCurveEnumerableERC20Test:test_bondingCurveSellBuyNoProfit(uint56,uint64,uint8) (runs: 256, μ: 844182, ~: 1246069)
NoArbExponentialCurveEnumerableETHTest:test_bondingCurveBuySellNoProfit(uint56,uint64,uint8) (runs: 256, μ: 303951, ~: 407907)
NoArbExponentialCurveEnumerableETHTest:test_bondingCurveSellBuyNoProfit(uint56,uint64,uint8) (runs: 256, μ: 302441, ~: 408372)
NoArbExponentialCurveMissingEnumerableERC20Test:test_bondingCurveBuySellNoProfit(uint56,uint64,uint8) (runs: 256, μ: 802110, ~: 1265233)
NoArbExponentialCurveMissingEnumerableERC20Test:test_bondingCurveSellBuyNoProfit(uint56,uint64,uint8) (runs: 256, μ: 792715, ~: 1215053)
NoArbExponentialCurveMissingEnumerableETHTest:test_bondingCurveBuySellNoProfit(uint56,uint64,uint8) (runs: 256, μ: 304756, ~: 415908)
NoArbExponentialCurveMissingEnumerableETHTest:test_bondingCurveSellBuyNoProfit(uint56,uint64,uint8) (runs: 256, μ: 250412, ~: 377356)
NoArbLinearCurveEnumerableERC20Test:test_bondingCurveBuySellNoProfit(uint56,uint64,uint8) (runs: 256, μ: 815398, ~: 1258953)
NoArbLinearCurveEnumerableERC20Test:test_bondingCurveSellBuyNoProfit(uint56,uint64,uint8) (runs: 256, μ: 804787, ~: 1247790)
NoArbLinearCurveEnumerableETHTest:test_bondingCurveBuySellNoProfit(uint56,uint64,uint8) (runs: 256, μ: 311204, ~: 409628)
NoArbLinearCurveEnumerableETHTest:test_bondingCurveSellBuyNoProfit(uint56,uint64,uint8) (runs: 256, μ: 290001, ~: 407749)
NoArbLinearCurveMissingEnumerableERC20Test:test_bondingCurveBuySellNoProfit(uint56,uint64,uint8) (runs: 256, μ: 809741, ~: 1266954)
NoArbLinearCurveMissingEnumerableERC20Test:test_bondingCurveSellBuyNoProfit(uint56,uint64,uint8) (runs: 256, μ: 804159, ~: 1216774)
NoArbLinearCurveMissingEnumerableETHTest:test_bondingCurveBuySellNoProfit(uint56,uint64,uint8) (runs: 256, μ: 310917, ~: 417629)
NoArbLinearCurveMissingEnumerableETHTest:test_bondingCurveSellBuyNoProfit(uint56,uint64,uint8) (runs: 256, μ: 247470, ~: 376733)
NoArbXykCurveEnumerableERC20Test:test_bondingCurveBuySellNoProfit(uint56,uint64,uint8) (runs: 256, μ: 839624, ~: 1259565)
NoArbXykCurveEnumerableERC20Test:test_bondingCurveSellBuyNoProfit(uint56,uint64,uint8) (runs: 256, μ: 879788, ~: 1248402)
NoArbXykCurveEnumerableETHTest:test_bondingCurveBuySellNoProfit(uint56,uint64,uint8) (runs: 256, μ: 322536, ~: 410240)
NoArbXykCurveEnumerableETHTest:test_bondingCurveSellBuyNoProfit(uint56,uint64,uint8) (runs: 256, μ: 310867, ~: 417713)
NoArbXykCurveMissingEnumerableERC20Test:test_bondingCurveBuySellNoProfit(uint56,uint64,uint8) (runs: 256, μ: 779669, ~: 1267566)
NoArbXykCurveMissingEnumerableERC20Test:test_bondingCurveSellBuyNoProfit(uint56,uint64,uint8) (runs: 256, μ: 744288, ~: 1217386)
NoArbXykCurveMissingEnumerableETHTest:test_bondingCurveBuySellNoProfit(uint56,uint64,uint8) (runs: 256, μ: 295663, ~: 418241)
NoArbXykCurveMissingEnumerableETHTest:test_bondingCurveSellBuyNoProfit(uint56,uint64,uint8) (runs: 256, μ: 260721, ~: 386697)
PAFExponentialCurveEnumerableERC20Test:testFail_callMint721() (gas: 19248)
PAFExponentialCurveEnumerableERC20Test:testFail_changeAssetRecipientForTrade() (gas: 10713)
PAFExponentialCurveEnumerableERC20Test:testFail_changeDeltaNotOwner() (gas: 18581)
Expand Down
12 changes: 12 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,18 @@ jobs:
with:
submodules: recursive

- uses: actions/setup-python@v4
with:
python-version: '3.9'

- name: Install eth_abi
run: pip install eth_abi

- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1
with:
version: nightly

- name: Install Foundry
uses: onbjerg/foundry-toolchain@v1
with:
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ solc:; nix-env -f https://github.com/dapphub/dapptools/archive/master.tar.gz -iA

# Build & test
build :; forge build --optimize
test :; forge test --optimize
test :; forge test --optimize --ffi
fuzz :; forge test -v --optimize
clean :; forge clean
lint :; yarn run lint
Expand Down
26 changes: 9 additions & 17 deletions src/bonding-curves/GDACurve.sol
Original file line number Diff line number Diff line change
Expand Up @@ -91,18 +91,14 @@ contract GDACurve is ICurve, CurveErrorCodes {
// This is equal to buySpotPrice * (alpha^n - 1) / (alpha - 1).
// We then divide the value by scalar^(lambda * timeElapsed) to factor in the exponential decay.
{
inputValue = spotPrice_.mul(alphaPowN - FixedPointMathLib.WAD);
inputValue = inputValue.div(alpha - FixedPointMathLib.WAD);
inputValue = inputValue.div(decayFactor);
inputValue =
spotPrice_.mul(alphaPowN - FixedPointMathLib.WAD).div(alpha - FixedPointMathLib.WAD).div(decayFactor);

// Account for the protocol fee, a flat percentage of the buy amount
protocolFee = inputValue.mul(protocolFeeMultiplier);

// Account for the trade fee, only for Trade pools
inputValue += inputValue.mul(feeMultiplier);

// Add the protocol fee to the required input amount
inputValue += protocolFee;
// Account for the trade and protocol fees
inputValue += inputValue.mul(feeMultiplier) + protocolFee;
}

// Update delta with the current timestamp
Expand Down Expand Up @@ -144,7 +140,6 @@ contract GDACurve is ICurve, CurveErrorCodes {
}

(uint256 alpha,,) = _parseDelta(delta);
// TODO: this value may overflow, should we cap the value?
uint256 alphaPowN = uint256(alpha).powu(numItems);

// The new spot price is multiplied by the time boost and divided by alpha^n so future
Expand All @@ -166,18 +161,15 @@ contract GDACurve is ICurve, CurveErrorCodes {
// and q is the number of items to sell.
// Our spot price implicity embeds the number of items already purchased and the previous time boost, so we just need to
// do some simple adjustments to get the current e^(lambda * t) and alpha^(m + q - 1) values.
outputValue = spotPrice_.mul(boostFactor).div(uint256(alpha).powu(numItems - 1));
outputValue = outputValue.mul(alphaPowN - FixedPointMathLib.WAD);
outputValue = outputValue.div(alpha - FixedPointMathLib.WAD);
outputValue = spotPrice_.mul(boostFactor).div(alphaPowN.div(alpha)).mul(alphaPowN - FixedPointMathLib.WAD).div(
alpha - FixedPointMathLib.WAD
);

// Account for the protocol fee, a flat percentage of the sell amount
protocolFee = outputValue.mul(protocolFeeMultiplier);

// Account for the trade fee, only for Trade pools
outputValue -= outputValue.mul(feeMultiplier);

// Remove the protocol fee from the output amount
outputValue -= protocolFee;
// Account for the trade and protocol fees
outputValue -= (outputValue.mul(feeMultiplier) + protocolFee);

// Update delta with the current timestamp
newDelta = _getNewDelta(delta);
Expand Down