Skip to content

Commit fbd53a8

Browse files
perf: assorted optimizations (#254)
* perf: optimize data.length checks * perf: cheaper cast * perf: faster lock * perf: faster sqrtu from solmate * perf: optimize > to != * perf: optimize locked * fix: lock operator mixup * fix: return name in sqrtu * fix: make sqrtu return uint128 again * perf: unchecked in factory * feat: restore abdk * ci: fix * ci: remove lint
1 parent e9257e6 commit fbd53a8

File tree

7 files changed

+37
-40
lines changed

7 files changed

+37
-40
lines changed

Diff for: .github/workflows/ci.yaml

+1-8
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ on:
66
- '**'
77
branches:
88
- 'main'
9+
pull_request:
910

1011
jobs:
1112
lint-test:
@@ -23,14 +24,6 @@ jobs:
2324

2425
- run: yarn install --ignore-scripts
2526

26-
- name: Lint
27-
uses: wearerequired/lint-action@v1
28-
with:
29-
github_token: ${{ secrets.github_token }}
30-
prettier: true
31-
auto_fix: true
32-
prettier_extensions: 'css,html,js,json,jsx,md,sass,scss,ts,tsx,vue,yaml,yml,sol'
33-
3427
- name: Typechain
3528
run: yarn typechain
3629

Diff for: contracts/PrimitiveEngine.sol

+12-12
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ contract PrimitiveEngine is IPrimitiveEngine {
6262
/// @inheritdoc IPrimitiveEngineView
6363
address public immutable override stable;
6464
/// @dev Reentrancy guard initialized to state
65-
uint8 private unlocked = 1;
65+
uint256 private locked = 1;
6666
/// @inheritdoc IPrimitiveEngineView
6767
mapping(bytes32 => Calibration) public override calibrations;
6868
/// @inheritdoc IPrimitiveEngineView
@@ -73,11 +73,11 @@ contract PrimitiveEngine is IPrimitiveEngine {
7373
mapping(address => mapping(bytes32 => uint256)) public override liquidity;
7474

7575
modifier lock() {
76-
if (unlocked != 1) revert LockedError();
76+
if (locked != 1) revert LockedError();
7777

78-
unlocked = 0;
78+
locked = 2;
7979
_;
80-
unlocked = 1;
80+
locked = 1;
8181
}
8282

8383
/// @notice Deploys an Engine with two tokens, a 'Risky' and 'Stable'
@@ -91,7 +91,7 @@ contract PrimitiveEngine is IPrimitiveEngine {
9191
(bool success, bytes memory data) = risky.staticcall(
9292
abi.encodeWithSelector(IERC20.balanceOf.selector, address(this))
9393
);
94-
if (!success || data.length < 32) revert BalanceError();
94+
if (!success || data.length != 32) revert BalanceError();
9595
return abi.decode(data, (uint256));
9696
}
9797

@@ -100,7 +100,7 @@ contract PrimitiveEngine is IPrimitiveEngine {
100100
(bool success, bytes memory data) = stable.staticcall(
101101
abi.encodeWithSelector(IERC20.balanceOf.selector, address(this))
102102
);
103-
if (!success || data.length < 32) revert BalanceError();
103+
if (!success || data.length != 32) revert BalanceError();
104104
return abi.decode(data, (uint256));
105105
}
106106

@@ -210,11 +210,11 @@ contract PrimitiveEngine is IPrimitiveEngine {
210210

211211
uint256 balRisky;
212212
uint256 balStable;
213-
if (delRisky > 0) balRisky = balanceRisky();
214-
if (delStable > 0) balStable = balanceStable();
213+
if (delRisky != 0) balRisky = balanceRisky();
214+
if (delStable != 0) balStable = balanceStable();
215215
IPrimitiveDepositCallback(msg.sender).depositCallback(delRisky, delStable, data); // agnostic payment
216-
if (delRisky > 0) checkRiskyBalance(balRisky + delRisky);
217-
if (delStable > 0) checkStableBalance(balStable + delStable);
216+
if (delRisky != 0) checkRiskyBalance(balRisky + delRisky);
217+
if (delStable != 0) checkStableBalance(balStable + delStable);
218218
emit Deposit(msg.sender, recipient, delRisky, delStable);
219219
}
220220

@@ -226,8 +226,8 @@ contract PrimitiveEngine is IPrimitiveEngine {
226226
) external override lock {
227227
if (delRisky == 0 && delStable == 0) revert ZeroDeltasError();
228228
margins.withdraw(delRisky, delStable); // state update
229-
if (delRisky > 0) IERC20(risky).safeTransfer(recipient, delRisky);
230-
if (delStable > 0) IERC20(stable).safeTransfer(recipient, delStable);
229+
if (delRisky != 0) IERC20(risky).safeTransfer(recipient, delRisky);
230+
if (delStable != 0) IERC20(stable).safeTransfer(recipient, delStable);
231231
emit Withdraw(msg.sender, recipient, delRisky, delStable);
232232
}
233233

Diff for: contracts/PrimitiveFactory.sol

+15-12
Original file line numberDiff line numberDiff line change
@@ -77,18 +77,21 @@ contract PrimitiveFactory is IPrimitiveFactory {
7777
if (riskyDecimals > 18 || riskyDecimals < 6) revert DecimalsError(riskyDecimals);
7878
if (stableDecimals > 18 || stableDecimals < 6) revert DecimalsError(stableDecimals);
7979

80-
uint256 scaleFactorRisky = 10**(18 - riskyDecimals);
81-
uint256 scaleFactorStable = 10**(18 - stableDecimals);
82-
uint256 lowestDecimals = (riskyDecimals > stableDecimals ? stableDecimals : riskyDecimals);
83-
uint256 minLiquidity = 10**(lowestDecimals / MIN_LIQUIDITY_FACTOR);
84-
args = Args({
85-
factory: factory,
86-
risky: risky,
87-
stable: stable,
88-
scaleFactorRisky: scaleFactorRisky,
89-
scaleFactorStable: scaleFactorStable,
90-
minLiquidity: minLiquidity
91-
}); // Engines call this to get constructor args
80+
unchecked {
81+
uint256 scaleFactorRisky = 10**(18 - riskyDecimals);
82+
uint256 scaleFactorStable = 10**(18 - stableDecimals);
83+
uint256 lowestDecimals = (riskyDecimals > stableDecimals ? stableDecimals : riskyDecimals);
84+
uint256 minLiquidity = 10**(lowestDecimals / MIN_LIQUIDITY_FACTOR);
85+
args = Args({
86+
factory: factory,
87+
risky: risky,
88+
stable: stable,
89+
scaleFactorRisky: scaleFactorRisky,
90+
scaleFactorStable: scaleFactorStable,
91+
minLiquidity: minLiquidity
92+
}); // Engines call this to get constructor args
93+
}
94+
9295
engine = address(new PrimitiveEngine{salt: keccak256(abi.encode(risky, stable))}());
9396
delete args;
9497
}

Diff for: contracts/libraries/Margin.sol

+4-4
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ library Margin {
2323
uint256 delRisky,
2424
uint256 delStable
2525
) internal {
26-
if (delRisky > 0) margin.balanceRisky += delRisky.toUint128();
27-
if (delStable > 0) margin.balanceStable += delStable.toUint128();
26+
if (delRisky != 0) margin.balanceRisky += delRisky.toUint128();
27+
if (delStable != 0) margin.balanceStable += delStable.toUint128();
2828
}
2929

3030
/// @notice Removes risky and stable token balance from `msg.sender`'s internal margin account
@@ -38,7 +38,7 @@ library Margin {
3838
uint256 delStable
3939
) internal returns (Data storage margin) {
4040
margin = margins[msg.sender];
41-
if (delRisky > 0) margin.balanceRisky -= delRisky.toUint128();
42-
if (delStable > 0) margin.balanceStable -= delStable.toUint128();
41+
if (delRisky != 0) margin.balanceRisky -= delRisky.toUint128();
42+
if (delStable != 0) margin.balanceStable -= delStable.toUint128();
4343
}
4444
}

Diff for: contracts/libraries/Reserve.sol

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ library Reserve {
3434
function update(Data storage res, uint32 blockTimestamp) internal {
3535
uint32 deltaTime = blockTimestamp - res.blockTimestamp;
3636
// overflow is desired
37-
if (deltaTime > 0) {
37+
if (deltaTime != 0) {
3838
unchecked {
3939
res.cumulativeRisky += uint256(res.reserveRisky) * deltaTime;
4040
res.cumulativeStable += uint256(res.reserveStable) * deltaTime;

Diff for: contracts/libraries/SafeCast.sol

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ pragma solidity >=0.5.0;
55
library SafeCast {
66
/// @notice reverts if x > type(uint128).max
77
function toUint128(uint256 x) internal pure returns (uint128 z) {
8-
require((z = uint128(x)) == x);
8+
require(x <= type(uint128).max);
9+
z = uint128(x);
910
}
1011
}

Diff for: contracts/test/callbacks/TestSwapCallback.sol

+2-2
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ abstract contract TestSwapCallback is Scenarios {
1717
address token0 = risky();
1818
address token1 = stable();
1919
address from = getCaller();
20-
if (delRisky > 0) IERC20(token0).transferFrom(from, msg.sender, delRisky);
21-
if (delStable > 0) IERC20(token1).transferFrom(from, msg.sender, delStable);
20+
if (delRisky != 0) IERC20(token0).transferFrom(from, msg.sender, delRisky);
21+
if (delStable != 0) IERC20(token1).transferFrom(from, msg.sender, delStable);
2222
}
2323
}

0 commit comments

Comments
 (0)