Skip to content

Commit f11a379

Browse files
committed
chore: fix post-mergem slither and solhint issues
1 parent 2533923 commit f11a379

7 files changed

Lines changed: 106 additions & 39 deletions

File tree

contracts/interfaces/IFPMMFactory.sol

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ interface IFPMMFactory {
149149
* @param _proxyAdmin The address of the proxy admin contract
150150
* @param _breakerBox The address of the breaker box contract
151151
* @param _governance The address of the governance contract
152+
* @param _fpmmImplementation The address of the FPMM implementation
152153
*/
153154
function initialize(
154155
address _sortedOracles,
@@ -197,6 +198,7 @@ interface IFPMMFactory {
197198

198199
/**
199200
* @notice Deploys a new FPMM for a token pair using the default parameters.
201+
* @param fpmmImplementation The address of the FPMM implementation
200202
* @param token0 The address of the first token
201203
* @param token1 The address of the second token
202204
* @param referenceRateFeedID The address of the reference rate feed

contracts/swap/FPMM.sol

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,8 +241,10 @@ contract FPMM is IFPMM, ReentrancyGuardUpgradeable, ERC20Upgradeable, OwnableUpg
241241

242242
(oraclePriceNumerator, oraclePriceDenominator) = _getRateFeed();
243243

244+
// slither-disable-start divide-before-multiply
244245
reservePriceNumerator = $.reserve1 * (1e18 / $.decimals1);
245246
reservePriceDenominator = $.reserve0 * (1e18 / $.decimals0);
247+
// slither-disable-end divide-before-multiply
246248

247249
uint256 oracleCrossProduct = oraclePriceNumerator * reservePriceDenominator;
248250
uint256 reserveCrossProduct = reservePriceNumerator * oraclePriceDenominator;
@@ -612,6 +614,7 @@ contract FPMM is IFPMM, ReentrancyGuardUpgradeable, ERC20Upgradeable, OwnableUpg
612614
FPMMStorage storage $ = _getFPMMStorage();
613615

614616
uint256 token0ValueInToken1 = convertWithRate(amount0, $.decimals0, 1e18, rateNumerator, rateDenominator);
617+
// slither-disable-next-line divide-before-multiply
615618
amount1 = amount1 * (1e18 / $.decimals1);
616619
return token0ValueInToken1 + amount1;
617620
}
@@ -666,6 +669,7 @@ contract FPMM is IFPMM, ReentrancyGuardUpgradeable, ERC20Upgradeable, OwnableUpg
666669
swapData.rateNumerator,
667670
swapData.rateDenominator
668671
);
672+
// slither-disable-next-line divide-before-multiply
669673
expectedAmount1In = expectedAmount1In / (1e18 / $.decimals1);
670674
uint256 minAmount1In = expectedAmount1In - (expectedAmount1In * $.rebalanceIncentive) / BASIS_POINTS_DENOMINATOR;
671675
require(swapData.amount1In >= minAmount1In, "FPMM: INSUFFICIENT_AMOUNT_1_IN");
@@ -720,6 +724,7 @@ contract FPMM is IFPMM, ReentrancyGuardUpgradeable, ERC20Upgradeable, OwnableUpg
720724
);
721725
uint256 totalFeeInToken1 = fee0InToken1 + fee1;
722726
// convert to 18 decimals
727+
// slither-disable-next-line divide-before-multiply
723728
totalFeeInToken1 = totalFeeInToken1 * (1e18 / $.decimals1);
724729

725730
// Check the reserve value is not decreased

contracts/swap/ReserveLiquidityStrategy.sol

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ contract ReserveLiquidityStrategy is LiquidityStrategy {
181181

182182
require(dec0 <= 1e18 && dec1 <= 1e18, "RLS: TOKEN_DECIMALS_TOO_LARGE");
183183

184+
// slither-disable-next-line uninitialized-local
184185
RebalanceParams memory params;
185186
params.stablePrecision = 1e18 / dec0;
186187
params.collateralPrecision = 1e18 / dec1;
@@ -228,11 +229,13 @@ contract ReserveLiquidityStrategy is LiquidityStrategy {
228229
(params.collateralReserve * oraclePriceDenominator);
229230
uint256 denominator = oraclePriceNumerator + ((oraclePriceNumerator * (BPS_SCALE - incentive)) / BPS_SCALE);
230231
uint256 stableOutRaw = numerator / denominator;
232+
// slither-disable-start divide-before-multiply
231233
stableOut = stableOutRaw / params.stablePrecision;
232234

233235
uint256 collateralInRaw = (stableOut * params.stablePrecision * oraclePriceNumerator) / oraclePriceDenominator;
234236

235237
collateralIn = collateralInRaw / params.collateralPrecision;
238+
// slither-disable-end divide-before-multiply
236239
}
237240

238241
/**
@@ -257,11 +260,13 @@ contract ReserveLiquidityStrategy is LiquidityStrategy {
257260
((params.stableReserve * oraclePriceNumerator) / oraclePriceDenominator);
258261
uint256 denominator = BPS_SCALE * 2 - incentive;
259262

263+
// slither-disable-start divide-before-multiply
260264
uint256 collateralOutRaw = (numerator * BPS_SCALE) / denominator;
261265
collateralOut = collateralOutRaw / params.collateralPrecision;
262266

263267
uint256 stablesInRaw = (collateralOut * params.collateralPrecision * oraclePriceDenominator) / oraclePriceNumerator;
264268
stablesIn = stablesInRaw / params.stablePrecision;
269+
// slither-disable-end divide-before-multiply
265270
}
266271

267272
/**

test/fork/BaseForkTest.sol

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,8 @@ abstract contract BaseForkTest is Test {
129129
}
130130

131131
function transferCeloFromReserve(address to, uint256 amount) internal {
132-
vm.prank(address(mentoReserve));
132+
vm.startPrank(address(mentoReserve));
133133
IERC20(lookup("GoldToken")).transfer(to, amount);
134+
vm.stopPrank();
134135
}
135136
}

test/fork/ForkTests.t.sol

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ contract Alfajores_P0E22_ExchangeForkTest is ExchangeForkTest(ALFAJORES_ID, 0, 2
9595

9696
contract Alfajores_P0E23_ExchangeForkTest is ExchangeForkTest(ALFAJORES_ID, 0, 23) {}
9797

98-
contract Celo_ChainForkTest is ChainForkTest(CELO_ID, 1, uints(21)) {}
98+
contract Celo_ChainForkTest is ChainForkTest(CELO_ID, 1, uints(24)) {}
9999

100100
contract Celo_P0E00_ExchangeForkTest is ExchangeForkTest(CELO_ID, 0, 0) {}
101101

@@ -139,6 +139,12 @@ contract Celo_P0E19_ExchangeForkTest is ExchangeForkTest(CELO_ID, 0, 19) {}
139139

140140
contract Celo_P0E20_ExchangeForkTest is ExchangeForkTest(CELO_ID, 0, 20) {}
141141

142+
contract Celo_P0E21_ExchangeForkTest is ExchangeForkTest(CELO_ID, 0, 21) {}
143+
144+
contract Celo_P0E22_ExchangeForkTest is ExchangeForkTest(CELO_ID, 0, 22) {}
145+
146+
contract Celo_P0E23_ExchangeForkTest is ExchangeForkTest(CELO_ID, 0, 23) {}
147+
142148
contract Celo_BancorExchangeProviderForkTest is BancorExchangeProviderForkTest(CELO_ID) {}
143149

144150
contract Celo_GoodDollarTradingLimitsForkTest is GoodDollarTradingLimitsForkTest(CELO_ID) {}

test/unit/swap/FPMM/FPMMFactory.t.sol

Lines changed: 0 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,6 @@ pragma solidity 0.8.18;
44
import { Test } from "forge-std/Test.sol";
55
import { FPMMFactory } from "contracts/swap/FPMMFactory.sol";
66
import { FPMM } from "contracts/swap/FPMM.sol";
7-
import { FPMMProxy } from "contracts/swap/FPMMProxy.sol";
8-
import { IERC20 } from "contracts/interfaces/IERC20.sol";
9-
import { ICreateX } from "contracts/interfaces/ICreateX.sol";
107
// solhint-disable-next-line max-line-length
118
import { ITransparentUpgradeableProxy } from "openzeppelin-contracts-next/contracts/proxy/transparent/TransparentUpgradeableProxy.sol";
129

@@ -752,40 +749,6 @@ abstract contract FPMMFactoryTest_DeployFPMM is FPMMFactoryTest {
752749
deploy("celo");
753750
}
754751

755-
function test_deployFPMM_whenSameSaltIsUsedByDifferentAddress_shouldNotDeployToSameAddress() public {
756-
vm.selectFork(celoFork);
757-
address alice = makeAddr("Alice");
758-
759-
vm.startPrank(alice);
760-
761-
bytes11 customProxySalt = bytes11(
762-
uint88(uint256(keccak256(abi.encodePacked(IERC20(token0Celo).symbol(), IERC20(token1Celo).symbol()))))
763-
);
764-
bytes32 proxySalt = bytes32(abi.encodePacked(address(factoryCelo), hex"00", customProxySalt));
765-
bytes memory proxyInitData = abi.encodeWithSelector(
766-
FPMM.initialize.selector,
767-
token0Celo,
768-
token1Celo,
769-
expectedSortedOracles,
770-
expectedReferenceRateFeedID,
771-
expectedBreakerBox,
772-
expectedGovernance
773-
);
774-
bytes memory proxyBytecode = abi.encodePacked(
775-
type(FPMMProxy).creationCode,
776-
abi.encode(fpmmImplementationCeloAddress, expectedProxyAdmin, proxyInitData)
777-
);
778-
779-
address aliceFPMMProxy = ICreateX(createX).deployCreate3(proxySalt, proxyBytecode);
780-
vm.stopPrank();
781-
782-
vm.prank(governanceCelo);
783-
deploy("celo");
784-
785-
address factoryProxy = address(factoryCelo.deployedFPMMs(token0Celo, token1Celo));
786-
assertNotEq(factoryProxy, aliceFPMMProxy);
787-
}
788-
789752
function test_deployFPMM_shouldDeploySameFPMMToSameAddressOnDifferentChains() public {
790753
vm.selectFork(celoFork);
791754
vm.prank(governanceCelo);
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
// SPDX-License-Identifier: GPL-3.0-or-later
2+
// solhint-disable func-name-mixedcase, var-name-mixedcase, state-visibility
3+
// solhint-disable const-name-snakecase, max-states-count, contract-name-camelcase
4+
// solhint-disable modifier-name-mixedcase,
5+
pragma solidity ^0.8;
6+
import { Test } from "mento-std/Test.sol";
7+
8+
import { ReserveLiquidityStrategy } from "contracts/swap/ReserveLiquidityStrategy.sol";
9+
import { IBreakerBox } from "contracts/interfaces/IBreakerBox.sol";
10+
import { MockERC20 } from "test/utils/mocks/MockERC20.sol";
11+
import { MockReserve } from "test/utils/mocks/MockReserve.sol";
12+
import { MockSortedOracles } from "test/utils/mocks/MockSortedOracles.sol";
13+
import { FPMM } from "contracts/swap/FPMM.sol";
14+
15+
contract StrategyIntegrationTest is Test {
16+
MockERC20 public token0;
17+
MockERC20 public token1;
18+
MockReserve public reserve;
19+
MockSortedOracles public sortedOracles;
20+
FPMM public pool;
21+
ReserveLiquidityStrategy public strategy;
22+
address public rateFeed;
23+
address public breakerBox;
24+
address public trader;
25+
26+
function setUp() public {
27+
breakerBox = makeAddr("BreakerBox");
28+
rateFeed = makeAddr("RateFeed");
29+
trader = makeAddr("Trader");
30+
31+
bytes memory tradingModeCalldata = abi.encodeWithSelector(IBreakerBox.getRateFeedTradingMode.selector, rateFeed);
32+
vm.mockCall(breakerBox, tradingModeCalldata, abi.encode(0));
33+
34+
token0 = new MockERC20("Token0", "T0", 18);
35+
token1 = new MockERC20("Token1", "T1", 6);
36+
reserve = new MockReserve();
37+
sortedOracles = new MockSortedOracles();
38+
sortedOracles.setMedianRate(rateFeed, 909884940000000000000000);
39+
pool = new FPMM(false);
40+
strategy = new ReserveLiquidityStrategy(false);
41+
strategy.initialize(address(reserve));
42+
pool.initialize(
43+
address(token0),
44+
address(token1),
45+
address(sortedOracles),
46+
rateFeed,
47+
true,
48+
address(breakerBox),
49+
address(this)
50+
);
51+
pool.setLiquidityStrategy(address(strategy), true);
52+
strategy.addPool(address(pool), 0, 50);
53+
54+
token0.mint(trader, 2e24);
55+
token1.mint(trader, 2e12);
56+
57+
token1.mint(address(reserve), 10e12);
58+
59+
vm.startPrank(trader);
60+
token0.transfer(address(pool), 1e24);
61+
token1.transfer(address(pool), 1e12);
62+
pool.mint(trader);
63+
vm.stopPrank();
64+
}
65+
66+
function test_rebalance_contraction() public {
67+
vm.startPrank(trader);
68+
token0.transfer(address(pool), 100_000 * 1e18);
69+
uint256 expectedAmountOut = pool.getAmountOut(100_000 * 1e18, address(token0));
70+
pool.swap(0, expectedAmountOut, trader, "");
71+
vm.stopPrank();
72+
73+
strategy.rebalance(address(pool));
74+
}
75+
76+
function test_rebalance_expansion() public {
77+
vm.startPrank(trader);
78+
token1.transfer(address(pool), 100_000 * 1e6);
79+
uint256 expectedAmountOut = pool.getAmountOut(100_000 * 1e6, address(token1));
80+
pool.swap(expectedAmountOut, 0, trader, "");
81+
vm.stopPrank();
82+
83+
strategy.rebalance(address(pool));
84+
}
85+
}

0 commit comments

Comments
 (0)