Skip to content
Merged
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
18 changes: 16 additions & 2 deletions certora/confs/GeneralAdapter1Reverts.conf
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,21 @@
"packages": [
"solmate=lib/permit2/lib/solmate"
],
"solc_via_ir": true,
"solc_via_ir_map": {
"Morpho": true,
"Bundler3": true,
"GeneralAdapter1": true,
"ERC4626Mock": true,
"ERC20Mock": true,
"ERC20NoRevert": true,
"ERC20USDT": true,
"ERC20Standard": true,
"SafeERC20": true,
"Address": true,
"Permit2Lib": true,
"Permit2": true,
"WETH9": false
},
"solc_optimize_map": {
"Morpho": "999999",
"Bundler3": "999999",
Expand All @@ -44,7 +58,7 @@
"Permit2": "999999",
"WETH9": "0"
},
"solc_map": {
"compiler_map": {
"Morpho": "solc-0.8.19",
"Bundler3": "solc-0.8.28",
"GeneralAdapter1": "solc-0.8.28",
Expand Down
2 changes: 1 addition & 1 deletion certora/confs/MorphoZeroConditions.conf
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
],
"solc_via_ir": true,
"solc_optimize": "999999",
"solc_map": {
"compiler_map": {
"Morpho": "solc-0.8.19",
"GeneralAdapter1": "solc-0.8.28"
},
Expand Down
2 changes: 1 addition & 1 deletion certora/confs/OnlyBundler3.conf
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
],
"solc_via_ir": true,
"solc_optimize": "99999",
"solc_map": {
"compiler_map": {
"Morpho": "solc-0.8.19",
"Bundler3": "solc-0.8.28",
"EthereumGeneralAdapter1": "solc-0.8.28",
Expand Down
2 changes: 1 addition & 1 deletion certora/confs/ReenterCaller.conf
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
],
"solc_via_ir": true,
"solc_optimize": "99999",
"solc_map": {
"compiler_map": {
"Morpho": "solc-0.8.19",
"Bundler3": "solc-0.8.28",
"EthereumGeneralAdapter1": "solc-0.8.28",
Expand Down
14 changes: 14 additions & 0 deletions foundry.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"lib/forge-std": {
"rev": "8f24d6b04c92975e0795b5868aa0d783251cdeaa"
},
"lib/morpho-blue": {
"rev": "8fd926254dd21bc6e5bf0ac401202a58f0ffa612"
},
"lib/openzeppelin-contracts": {
"rev": "49cd64565aafa5b8f6863bf60a30ef015861614c"
},
"lib/permit2": {
"rev": "576f549a7351814f112edcc42f3f8472d1712673"
}
}
24 changes: 18 additions & 6 deletions foundry.toml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
[profile.default]
names = true
fs_permissions = [
{ access = "read", path = "./out/"},
{ access = "read", path = "./config/"}
{ access = "read", path = "./out/" },
{ access = "read", path = "./config/" },
]
libs = ["lib"]
ignored_error_codes = ["transient-storage"]
Expand All @@ -16,12 +16,24 @@ evm_version = "cancun"
[profile.default.fuzz]
runs = 64

[profile.default.rpc_endpoints]
[profile.default.fmt]
wrap_comments = true

[lint]
exclude_lints = [
"unsafe-typecast",
"unaliased-plain-import",
"unused-import",
"mixed-case-variable",
"screaming-snake-case-const",
"erc20-unchecked-transfer",
"unwrapped-modifier-logic",
"mixed-case-function",
]

[rpc_endpoints]
ethereum = "https://eth-mainnet.g.alchemy.com/v2/${ALCHEMY_KEY}"
base = "https://base-mainnet.g.alchemy.com/v2/${ALCHEMY_KEY}"
tenderly = "https://rpc.tenderly.co/fork/${TENDERLY_FORK_ID}"

[profile.default.fmt]
wrap_comments = true

# See more config options https://github.com/foundry-rs/foundry/tree/master/crates/config
10 changes: 6 additions & 4 deletions src/adapters/ParaswapAdapter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -202,10 +202,12 @@ contract ParaswapAdapter is CoreAdapter, IParaswapAdapter {
/// @notice Sets exact amount in `callData` to `exactAmount`.
/// @notice Proportionally scale limit amount in `callData`.
/// @notice If `offsets.quotedAmount` is not zero, proportionally scale quoted amount in `callData`.
function updateAmounts(bytes memory callData, Offsets calldata offsets, uint256 exactAmount, Math.Rounding rounding)
internal
pure
{
function updateAmounts(
bytes memory callData,
Offsets calldata offsets,
uint256 exactAmount,
Math.Rounding rounding
) internal pure {
uint256 oldExactAmount = callData.get(offsets.exactAmount);
callData.set(offsets.exactAmount, exactAmount);

Expand Down
4 changes: 1 addition & 3 deletions src/interfaces/IAaveV3Optimizer.sol
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,7 @@ interface IAaveV3Optimizer {
uint256 deadline,
Signature calldata signature
) external returns (uint256 supplied);
function supplyCollateral(address underlying, uint256 amount, address onBehalf)
external
returns (uint256 supplied);
function supplyCollateral(address underlying, uint256 amount, address onBehalf) external returns (uint256 supplied);
function supplyCollateralWithPermit(
address underlying,
uint256 amount,
Expand Down
5 changes: 2 additions & 3 deletions test/MorphoAdapterLocalTest.sol
Original file line number Diff line number Diff line change
Expand Up @@ -724,9 +724,8 @@ contract MorphoAdapterLocalTest is LocalTest {
uint256 currentBorrowPower = totalBorrowPower - borrowed;
if (currentBorrowPower == 0) return;

uint256 maxShares = MorphoUtilsLib.min(currentBorrowPower, availableLiquidity).toSharesDown(
vars.expectedTotalBorrow, vars.expectedBorrowShares
);
uint256 maxShares = MorphoUtilsLib.min(currentBorrowPower, availableLiquidity)
.toSharesDown(vars.expectedTotalBorrow, vars.expectedBorrowShares);
if (maxShares < MIN_AMOUNT) return;
shares = bound(shares % maxShares, MIN_AMOUNT, maxShares);

Expand Down
54 changes: 45 additions & 9 deletions test/ParaswapAdapterLocalTest.sol
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,15 @@ contract ParaswapAdapterLocalTest is LocalTest {
vm.assume(sender != address(bundler3));
vm.expectRevert(ErrorsLib.UnauthorizedSender.selector);
vm.prank(sender);
paraswapAdapter.buy(address(augustus), new bytes(32), address(0), address(0), 0, Offsets(0, 0, 0), address(0));
paraswapAdapter.buy(
address(augustus),
new bytes(32),
address(0),
address(0),
0,
Offsets({exactAmount: 0, limitAmount: 0, quotedAmount: 0}),
address(0)
);
}

function testBuyMorphoDebtUnauthorized(address sender) public {
Expand All @@ -64,7 +72,7 @@ contract ParaswapAdapterLocalTest is LocalTest {
_swapCalldata(0, 1, 1, 1),
address(0),
marketParams,
Offsets(0, 32, 64),
Offsets({exactAmount: 0, limitAmount: 32, quotedAmount: 64}),
address(this),
address(0)
);
Expand All @@ -75,7 +83,13 @@ contract ParaswapAdapterLocalTest is LocalTest {
vm.expectRevert(ErrorsLib.UnauthorizedSender.selector);
vm.prank(sender);
paraswapAdapter.sell(
address(augustus), new bytes(32), address(0), address(0), false, Offsets(0, 0, 0), address(0)
address(augustus),
new bytes(32),
address(0),
address(0),
false,
Offsets({exactAmount: 0, limitAmount: 0, quotedAmount: 0}),
address(0)
);
}

Expand All @@ -85,7 +99,15 @@ contract ParaswapAdapterLocalTest is LocalTest {
vm.prank(address(bundler3));

vm.expectRevert(ErrorsLib.InvalidAugustus.selector);
paraswapAdapter.sell(_augustus, new bytes(32), address(0), address(0), false, Offsets(0, 0, 0), address(0));
paraswapAdapter.sell(
_augustus,
new bytes(32),
address(0),
address(0),
false,
Offsets({exactAmount: 0, limitAmount: 0, quotedAmount: 0}),
address(0)
);
}

function testAugustusInRegistryBuyCheck(address _augustus) public {
Expand All @@ -94,7 +116,15 @@ contract ParaswapAdapterLocalTest is LocalTest {
vm.prank(address(bundler3));

vm.expectRevert(ErrorsLib.InvalidAugustus.selector);
paraswapAdapter.buy(_augustus, new bytes(32), address(0), address(0), 0, Offsets(0, 0, 0), address(0));
paraswapAdapter.buy(
_augustus,
new bytes(32),
address(0),
address(0),
0,
Offsets({exactAmount: 0, limitAmount: 0, quotedAmount: 0}),
address(0)
);
}

function testMinDestAmountZeroBuy() public {
Expand All @@ -113,7 +143,13 @@ contract ParaswapAdapterLocalTest is LocalTest {
vm.expectRevert(ErrorsLib.ZeroAddress.selector);
vm.prank(address(bundler3));
paraswapAdapter.sell(
address(augustus), new bytes(32), address(0), address(0), false, Offsets(0, 0, 0), address(0)
address(augustus),
new bytes(32),
address(0),
address(0),
false,
Offsets({exactAmount: 0, limitAmount: 0, quotedAmount: 0}),
address(0)
);
}

Expand All @@ -126,7 +162,7 @@ contract ParaswapAdapterLocalTest is LocalTest {
address(0),
address(0),
1,
Offsets(0, 0, 0),
Offsets({exactAmount: 0, limitAmount: 0, quotedAmount: 0}),
address(0)
);
}
Expand Down Expand Up @@ -197,7 +233,7 @@ contract ParaswapAdapterLocalTest is LocalTest {
address(collateralToken),
address(loanToken),
true,
Offsets(offset, offset + 32, quotedOffset),
Offsets({exactAmount: offset, limitAmount: offset + 32, quotedAmount: quotedOffset}),
address(1)
)
)
Expand Down Expand Up @@ -271,7 +307,7 @@ contract ParaswapAdapterLocalTest is LocalTest {
address(collateralToken),
address(loanToken),
adjustedExact,
Offsets(offset, offset + 32, quotedOffset),
Offsets({exactAmount: offset, limitAmount: offset + 32, quotedAmount: quotedOffset}),
address(1)
)
)
Expand Down
41 changes: 30 additions & 11 deletions test/ParaswapMorphoBundlesLocalTest.sol
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,13 @@ contract ParaswapMorphoBundlesLocalTest is LocalTest {

// Market with new loan token

marketParamsLoan2 =
MarketParams(address(loanToken2), address(collateralToken), address(oracle), address(irm), LLTV);
marketParamsLoan2 = MarketParams({
loanToken: address(loanToken2),
collateralToken: address(collateralToken),
oracle: address(oracle),
irm: address(irm),
lltv: LLTV
});
idLoan2 = marketParamsLoan2.id();

vm.prank(OWNER);
Expand All @@ -57,17 +62,27 @@ contract ParaswapMorphoBundlesLocalTest is LocalTest {
vm.label(address(collateralToken2), "collateralToken2");

// Market with new collateral token
marketParamsCollateral2 =
MarketParams(address(loanToken), address(collateralToken2), address(oracle), address(irm), LLTV);
marketParamsCollateral2 = MarketParams({
loanToken: address(loanToken),
collateralToken: address(collateralToken2),
oracle: address(oracle),
irm: address(irm),
lltv: LLTV
});
idCollateral2 = marketParamsCollateral2.id();

vm.prank(OWNER);
morpho.createMarket(marketParamsCollateral2);

// Market with both new loan and collateral token

marketParamsAll2 =
MarketParams(address(loanToken2), address(collateralToken2), address(oracle), address(irm), LLTV);
marketParamsAll2 = MarketParams({
loanToken: address(loanToken2),
collateralToken: address(collateralToken2),
oracle: address(oracle),
irm: address(irm),
lltv: LLTV
});
idAll2 = marketParamsAll2.id();

vm.prank(OWNER);
Expand Down Expand Up @@ -255,9 +270,11 @@ contract ParaswapMorphoBundlesLocalTest is LocalTest {
}

// Method: withdraw all, sell all, supply all
function _createFullSupplySwapBundle(address user, MarketParams memory sourceParams, MarketParams memory destParams)
internal
{
function _createFullSupplySwapBundle(
address user,
MarketParams memory sourceParams,
MarketParams memory destParams
) internal {
_createFullWithdrawAndSwapBundle(user, sourceParams, destParams.loanToken, address(generalAdapter1));
bundle.push(_morphoSupply(destParams, type(uint256).max, 0, type(uint256).max, user, hex""));
}
Expand Down Expand Up @@ -419,7 +436,8 @@ contract ParaswapMorphoBundlesLocalTest is LocalTest {
MarketParams memory sourceParams,
MarketParams memory destParams
) internal {
uint256 borrowAssetsOverestimate = morpho.expectedBorrowAssets(sourceParams, USER) * 101 / 100;
uint256 borrowAssetsOverestimate =
morpho.expectedBorrowAssets(sourceParams, USER) * 101 / 100;

callbackBundle.push(_morphoWithdrawCollateral(sourceParams, type(uint256).max, address(paraswapAdapter)));
callbackBundle.push(
Expand Down Expand Up @@ -476,7 +494,8 @@ contract ParaswapMorphoBundlesLocalTest is LocalTest {
MarketParams memory sourceParams,
MarketParams memory destParams
) internal {
uint256 borrowAssetsOverestimate = morpho.expectedBorrowAssets(sourceParams, USER) * 101 / 100;
uint256 borrowAssetsOverestimate =
morpho.expectedBorrowAssets(sourceParams, USER) * 101 / 100;
uint256 destCollateralOverestimate = morpho.collateral(sourceParams.id(), USER) * 101 / 100;

callbackBundle.push(_morphoSupplyCollateral(destParams, type(uint256).max, user, hex""));
Expand Down
Loading