From 8ccac62f1dc9263491ba0bbdaa72bc38696acd71 Mon Sep 17 00:00:00 2001 From: Vectorized Date: Mon, 29 Aug 2022 23:04:03 +0000 Subject: [PATCH 1/3] Minor lnWad optimization --- .gas-snapshot | 20 ++++++++++---------- src/utils/SignedWadMath.sol | 25 +++++++++++++++++-------- 2 files changed, 27 insertions(+), 18 deletions(-) diff --git a/.gas-snapshot b/.gas-snapshot index b88bd7d..e7281fc 100644 --- a/.gas-snapshot +++ b/.gas-snapshot @@ -4,15 +4,15 @@ LinearNFTTest:testMintNFT() (gas: 86166) LinearVRGDATest:testAlwaysTargetPriceInRightConditions(uint256) (runs: 256, μ: 10109, ~: 10109) LinearVRGDATest:testPricingBasic() (gas: 9972) LinearVRGDATest:testTargetPrice() (gas: 10749) -LogisticNFTTest:testCannotMintMoreThanMax() (gas: 4437960) -LogisticNFTTest:testCannotUnderpayForNFTMint() (gas: 40767) -LogisticNFTTest:testMintAllNFT() (gas: 4426938) -LogisticNFTTest:testMintNFT() (gas: 86855) -LogisticVRGDATest:testAlwaysTargetPriceInRightConditions(uint256) (runs: 256, μ: 11692, ~: 11692) +LogisticNFTTest:testCannotMintMoreThanMax() (gas: 4435760) +LogisticNFTTest:testCannotUnderpayForNFTMint() (gas: 40745) +LogisticNFTTest:testMintAllNFT() (gas: 4424738) +LogisticNFTTest:testMintNFT() (gas: 86833) +LogisticVRGDATest:testAlwaysTargetPriceInRightConditions(uint256) (runs: 256, μ: 11648, ~: 11648) LogisticVRGDATest:testFailOverflowForBeyondLimitTokens(uint256,uint256) (runs: 256, μ: 10278, ~: 10278) -LogisticVRGDATest:testGetTargetSaleTimeDoesNotRevertEarly() (gas: 6147) +LogisticVRGDATest:testGetTargetSaleTimeDoesNotRevertEarly() (gas: 6125) LogisticVRGDATest:testGetTargetSaleTimeRevertsWhenExpected() (gas: 8533) -LogisticVRGDATest:testNoOverflowForAllTokens(uint256,uint256) (runs: 256, μ: 11229, ~: 11229) -LogisticVRGDATest:testNoOverflowForMostTokens(uint256,uint256) (runs: 256, μ: 11385, ~: 11528) -LogisticVRGDATest:testPricingBasic() (gas: 10762) -LogisticVRGDATest:testTargetPrice() (gas: 12246) +LogisticVRGDATest:testNoOverflowForAllTokens(uint256,uint256) (runs: 256, μ: 11207, ~: 11207) +LogisticVRGDATest:testNoOverflowForMostTokens(uint256,uint256) (runs: 256, μ: 11380, ~: 11506) +LogisticVRGDATest:testPricingBasic() (gas: 10740) +LogisticVRGDATest:testTargetPrice() (gas: 12202) diff --git a/src/utils/SignedWadMath.sol b/src/utils/SignedWadMath.sol index 75e8e19..224eee2 100644 --- a/src/utils/SignedWadMath.sol +++ b/src/utils/SignedWadMath.sol @@ -149,14 +149,23 @@ function wadLn(int256 x) pure returns (int256 r) { // and add ln(2**96 / 10**18) at the end. assembly { - r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x)) - r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x)))) - r := or(r, shl(5, lt(0xffffffff, shr(r, x)))) - r := or(r, shl(4, lt(0xffff, shr(r, x)))) - r := or(r, shl(3, lt(0xff, shr(r, x)))) - r := or(r, shl(2, lt(0xf, shr(r, x)))) - r := or(r, shl(1, lt(0x3, shr(r, x)))) - r := or(r, lt(0x1, shr(r, x))) + let v := x + r := shl(7, lt(0xffffffffffffffffffffffffffffffff, v)) + r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, v)))) + r := or(r, shl(5, lt(0xffffffff, shr(r, v)))) + + // For the remaining 32 bits, use a De Bruijn lookup. + // See: https://graphics.stanford.edu/~seander/bithacks.html + v := shr(r, v) + v := or(v, shr(1, v)) + v := or(v, shr(2, v)) + v := or(v, shr(4, v)) + v := or(v, shr(8, v)) + v := or(v, shr(16, v)) + + // prettier-ignore + r := or(r, byte(and(31, shr(27, mul(v, 0x07c4acdd))), + 0x0009010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f)) } // Reduce range of x to (1, 2) * 2**96 From 1434a0b3ec6bed51c23965af2490371e35f64824 Mon Sep 17 00:00:00 2001 From: Vectorized Date: Tue, 30 Aug 2022 21:00:21 +0000 Subject: [PATCH 2/3] Micro optimization --- src/utils/SignedWadMath.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/SignedWadMath.sol b/src/utils/SignedWadMath.sol index 224eee2..53e61f7 100644 --- a/src/utils/SignedWadMath.sol +++ b/src/utils/SignedWadMath.sol @@ -164,7 +164,7 @@ function wadLn(int256 x) pure returns (int256 r) { v := or(v, shr(16, v)) // prettier-ignore - r := or(r, byte(and(31, shr(27, mul(v, 0x07c4acdd))), + r := or(r, byte(shr(251, mul(v, shl(224, 0x07c4acdd))), 0x0009010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f)) } From 3bcbc25f714375236ab551ecd40d9c19569f88cf Mon Sep 17 00:00:00 2001 From: Vectorized Date: Tue, 30 Aug 2022 21:01:19 +0000 Subject: [PATCH 3/3] Snapshot --- .gas-snapshot | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/.gas-snapshot b/.gas-snapshot index e7281fc..7580cfb 100644 --- a/.gas-snapshot +++ b/.gas-snapshot @@ -4,15 +4,15 @@ LinearNFTTest:testMintNFT() (gas: 86166) LinearVRGDATest:testAlwaysTargetPriceInRightConditions(uint256) (runs: 256, μ: 10109, ~: 10109) LinearVRGDATest:testPricingBasic() (gas: 9972) LinearVRGDATest:testTargetPrice() (gas: 10749) -LogisticNFTTest:testCannotMintMoreThanMax() (gas: 4435760) -LogisticNFTTest:testCannotUnderpayForNFTMint() (gas: 40745) -LogisticNFTTest:testMintAllNFT() (gas: 4424738) -LogisticNFTTest:testMintNFT() (gas: 86833) -LogisticVRGDATest:testAlwaysTargetPriceInRightConditions(uint256) (runs: 256, μ: 11648, ~: 11648) +LogisticNFTTest:testCannotMintMoreThanMax() (gas: 4435160) +LogisticNFTTest:testCannotUnderpayForNFTMint() (gas: 40739) +LogisticNFTTest:testMintAllNFT() (gas: 4424138) +LogisticNFTTest:testMintNFT() (gas: 86827) +LogisticVRGDATest:testAlwaysTargetPriceInRightConditions(uint256) (runs: 256, μ: 11636, ~: 11636) LogisticVRGDATest:testFailOverflowForBeyondLimitTokens(uint256,uint256) (runs: 256, μ: 10278, ~: 10278) -LogisticVRGDATest:testGetTargetSaleTimeDoesNotRevertEarly() (gas: 6125) +LogisticVRGDATest:testGetTargetSaleTimeDoesNotRevertEarly() (gas: 6119) LogisticVRGDATest:testGetTargetSaleTimeRevertsWhenExpected() (gas: 8533) -LogisticVRGDATest:testNoOverflowForAllTokens(uint256,uint256) (runs: 256, μ: 11207, ~: 11207) -LogisticVRGDATest:testNoOverflowForMostTokens(uint256,uint256) (runs: 256, μ: 11380, ~: 11506) -LogisticVRGDATest:testPricingBasic() (gas: 10740) -LogisticVRGDATest:testTargetPrice() (gas: 12202) +LogisticVRGDATest:testNoOverflowForAllTokens(uint256,uint256) (runs: 256, μ: 11201, ~: 11201) +LogisticVRGDATest:testNoOverflowForMostTokens(uint256,uint256) (runs: 256, μ: 11374, ~: 11500) +LogisticVRGDATest:testPricingBasic() (gas: 10734) +LogisticVRGDATest:testTargetPrice() (gas: 12190)