From 2f6116077ea5e10acc312e2419d832841c452fd5 Mon Sep 17 00:00:00 2001 From: alcueca Date: Tue, 8 Aug 2023 22:12:19 +0100 Subject: [PATCH 1/6] use the Registry to initialize the uniswap wrapper --- .gitmodules | 3 +++ lib/registry | 1 + src/uniswapV3/UniswapV3Wrapper.sol | 15 ++++++++++----- test/UniswapV3Wrapper.t.sol | 5 ++++- 4 files changed, 18 insertions(+), 6 deletions(-) create mode 160000 lib/registry diff --git a/.gitmodules b/.gitmodules index 024e485..520b394 100644 --- a/.gitmodules +++ b/.gitmodules @@ -15,3 +15,6 @@ [submodule "lib/erc7399"] path = lib/erc7399 url = https://github.com/alcueca/erc7399 +[submodule "lib/registry"] + path = lib/registry + url = https://github.com/alcueca/registry diff --git a/lib/registry b/lib/registry new file mode 160000 index 0000000..8e98080 --- /dev/null +++ b/lib/registry @@ -0,0 +1 @@ +Subproject commit 8e98080c90eae718af721695dc07852d9d43db5a diff --git a/src/uniswapV3/UniswapV3Wrapper.sol b/src/uniswapV3/UniswapV3Wrapper.sol index c33a1ad..c589fa2 100644 --- a/src/uniswapV3/UniswapV3Wrapper.sol +++ b/src/uniswapV3/UniswapV3Wrapper.sol @@ -2,6 +2,8 @@ // Thanks to sunnyRK and yashnaman pragma solidity ^0.8.0; +import { Registry } from "lib/registry/src/Registry.sol"; + import { IUniswapV3FlashCallback } from "./interfaces/callback/IUniswapV3FlashCallback.sol"; import { IUniswapV3Pool } from "./interfaces/IUniswapV3Pool.sol"; import { PoolAddress } from "./interfaces/PoolAddress.sol"; @@ -22,11 +24,14 @@ contract UniswapV3Wrapper is BaseWrapper, IUniswapV3FlashCallback { address usdc; address usdt; - /// @param factory_ Uniswap v3 UniswapV3Factory address - /// @param weth_ Weth contract used in Uniswap v3 Pairs - /// @param usdc_ usdc contract used in Uniswap v3 Pairs - /// @param usdt_ usdt contract used in Uniswap v3 Pairs - constructor(address factory_, address weth_, address usdc_, address usdt_) { + /// @param registry Registry storing constructor parameters + constructor(Registry registry) { + // @param factory_ Uniswap v3 UniswapV3Factory address + // @param weth_ Weth contract used in Uniswap v3 Pairs + // @param usdc_ usdc contract used in Uniswap v3 Pairs + // @param usdt_ usdt contract used in Uniswap v3 Pairs + (address factory_, address weth_, address usdc_, address usdt_) = + abi.decode(registry.get("UniswapV3Wrapper"), (address, address, address, address)); factory = factory_; weth = weth_; usdc = usdc_; diff --git a/test/UniswapV3Wrapper.t.sol b/test/UniswapV3Wrapper.t.sol index 99d4e25..b869bbd 100644 --- a/test/UniswapV3Wrapper.t.sol +++ b/test/UniswapV3Wrapper.t.sol @@ -6,6 +6,7 @@ import { console2 } from "forge-std/console2.sol"; import { StdCheats } from "forge-std/StdCheats.sol"; import { ERC20 } from "solmate/tokens/ERC20.sol"; +import { Registry } from "lib/registry/src/Registry.sol"; import { MockBorrower } from "./MockBorrower.sol"; import { UniswapV3Wrapper } from "../src/uniswapV3/UniswapV3Wrapper.sol"; @@ -37,7 +38,9 @@ contract UniswapV3WrapperTest is PRBTest, StdCheats { weth = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2; wbtc = 0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599; - wrapper = new UniswapV3Wrapper(address(factory), weth, usdc, usdt); + Registry registry = new Registry(address(this)); + registry.set("UniswapV3Wrapper", abi.encode(address(factory), weth, usdc, usdt)); + wrapper = new UniswapV3Wrapper(registry); borrower = new MockBorrower(wrapper); deal(address(usdc), address(this), 1e6); // For fees } From f8d3a215fed57526e1bdba91f8e21c4ba3c4c19b Mon Sep 17 00:00:00 2001 From: "ultrasecr.eth" <241804+ultrasecreth@users.noreply.github.com> Date: Tue, 8 Aug 2023 23:33:44 +0100 Subject: [PATCH 2/6] Make assets immutable --- src/uniswapV3/UniswapV3Wrapper.sol | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/uniswapV3/UniswapV3Wrapper.sol b/src/uniswapV3/UniswapV3Wrapper.sol index c589fa2..aa3cb97 100644 --- a/src/uniswapV3/UniswapV3Wrapper.sol +++ b/src/uniswapV3/UniswapV3Wrapper.sol @@ -20,9 +20,9 @@ contract UniswapV3Wrapper is BaseWrapper, IUniswapV3FlashCallback { address public immutable factory; // DEFAULT ASSETS - address weth; - address usdc; - address usdt; + address public immutable weth; + address public immutable usdc; + address public immutable usdt; /// @param registry Registry storing constructor parameters constructor(Registry registry) { @@ -30,12 +30,7 @@ contract UniswapV3Wrapper is BaseWrapper, IUniswapV3FlashCallback { // @param weth_ Weth contract used in Uniswap v3 Pairs // @param usdc_ usdc contract used in Uniswap v3 Pairs // @param usdt_ usdt contract used in Uniswap v3 Pairs - (address factory_, address weth_, address usdc_, address usdt_) = - abi.decode(registry.get("UniswapV3Wrapper"), (address, address, address, address)); - factory = factory_; - weth = weth_; - usdc = usdc_; - usdt = usdt_; + (factory, weth, usdc, usdt) = abi.decode(registry.get("UniswapV3Wrapper"), (address, address, address, address)); } /** From 0ca02b83e04dd0d1639485fb662eaeabee3fce37 Mon Sep 17 00:00:00 2001 From: "ultrasecr.eth" <241804+ultrasecreth@users.noreply.github.com> Date: Tue, 8 Aug 2023 23:45:16 +0100 Subject: [PATCH 3/6] Lint --- .gitignore | 1 + package.json | 2 +- src/BaseWrapper.sol | 2 +- src/aave/AaveWrapper.sol | 12 ++++++++---- src/aave/interfaces/DataTypes.sol | 2 +- src/aave/interfaces/Errors.sol | 2 +- src/aave/interfaces/IFlashLoanSimpleReceiver.sol | 2 +- src/aave/interfaces/IPool.sol | 2 +- src/aave/interfaces/IPoolAddressesProvider.sol | 2 +- src/aave/interfaces/ReserveConfiguration.sol | 2 +- src/balancer/BalancerWrapper.sol | 10 ++++++---- src/balancer/interfaces/IFlashLoanRecipient.sol | 2 +- src/balancer/interfaces/IFlashLoaner.sol | 2 +- src/balancer/interfaces/IProtocolFeesCollector.sol | 2 +- src/erc3156/ERC3156Wrapper.sol | 4 ++-- src/uniswapV3/UniswapV3Wrapper.sol | 10 +++++----- src/utils/Arrays.sol | 2 +- src/utils/RevertMsgExtractor.sol | 3 ++- src/utils/TransferHelper.sol | 7 ++++--- test/MockBorrower.sol | 2 +- 20 files changed, 41 insertions(+), 32 deletions(-) diff --git a/.gitignore b/.gitignore index 27c05e8..85c3b8a 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ cache node_modules out +.idea # files *.env diff --git a/package.json b/package.json index a11e7d7..9dc82e4 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "scripts": { "clean": "rm -rf cache out", "lint": "pnpm lint:sol && pnpm prettier:check", - "lint:sol": "forge fmt --check && pnpm solhint {script,src,test}/**/*.sol", + "lint:sol": "forge fmt --check && pnpm solhint src/**/*.sol", "prettier:check": "prettier --check **/*.{json,md,yml} --ignore-path=.prettierignore", "prettier:write": "prettier --write **/*.{json,md,yml} --ignore-path=.prettierignore" } diff --git a/src/BaseWrapper.sol b/src/BaseWrapper.sol index 342a7b1..ba45327 100644 --- a/src/BaseWrapper.sol +++ b/src/BaseWrapper.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // Thanks to ultrasecr.eth -pragma solidity ^0.8.0; +pragma solidity ^0.8.19; import "erc7399/IERC7399.sol"; diff --git a/src/aave/AaveWrapper.sol b/src/aave/AaveWrapper.sol index 2d6e071..91bd022 100644 --- a/src/aave/AaveWrapper.sol +++ b/src/aave/AaveWrapper.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // Thanks to ultrasecr.eth -pragma solidity ^0.8.0; +pragma solidity ^0.8.19; import { IPool } from "./interfaces/IPool.sol"; import { DataTypes } from "./interfaces/DataTypes.sol"; @@ -12,14 +12,18 @@ import { FixedPointMathLib } from "lib/solmate/src/utils/FixedPointMathLib.sol"; import { BaseWrapper, IERC7399, ERC20 } from "../BaseWrapper.sol"; - /// @dev Aave Flash Lender that uses the Aave Pool as source of liquidity. /// Aave doesn't allow flow splitting or pushing repayments, so this wrapper is completely vanilla. contract AaveWrapper is BaseWrapper, IFlashLoanSimpleReceiver { using FixedPointMathLib for uint256; using ReserveConfiguration for DataTypes.ReserveConfigurationMap; + error NotPool(); + error NotInitiator(); + + // solhint-disable-next-line var-name-mixedcase IPoolAddressesProvider public immutable ADDRESSES_PROVIDER; + // solhint-disable-next-line var-name-mixedcase IPool public immutable POOL; constructor(IPoolAddressesProvider provider) { @@ -64,8 +68,8 @@ contract AaveWrapper is BaseWrapper, IFlashLoanSimpleReceiver { override returns (bool) { - require(msg.sender == address(POOL), "AaveFlashLoanProvider: not pool"); - require(initiator == address(this), "AaveFlashLoanProvider: not initiator"); + if (msg.sender != address(POOL)) revert NotPool(); + if (initiator != address(this)) revert NotInitiator(); bridgeToCallback(asset, amount, fee, params); diff --git a/src/aave/interfaces/DataTypes.sol b/src/aave/interfaces/DataTypes.sol index 20d2f8e..12bd0e8 100644 --- a/src/aave/interfaces/DataTypes.sol +++ b/src/aave/interfaces/DataTypes.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BUSL-1.1 -pragma solidity ^0.8.0; +pragma solidity ^0.8.19; library DataTypes { struct ReserveData { diff --git a/src/aave/interfaces/Errors.sol b/src/aave/interfaces/Errors.sol index c948b15..9ce1e48 100644 --- a/src/aave/interfaces/Errors.sol +++ b/src/aave/interfaces/Errors.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BUSL-1.1 -pragma solidity ^0.8.0; +pragma solidity ^0.8.19; /** * @title Errors library diff --git a/src/aave/interfaces/IFlashLoanSimpleReceiver.sol b/src/aave/interfaces/IFlashLoanSimpleReceiver.sol index 2150092..12a9a3a 100644 --- a/src/aave/interfaces/IFlashLoanSimpleReceiver.sol +++ b/src/aave/interfaces/IFlashLoanSimpleReceiver.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: AGPL-3.0 -pragma solidity ^0.8.0; +pragma solidity ^0.8.19; import { IPoolAddressesProvider } from "./IPoolAddressesProvider.sol"; import { IPool } from "./IPool.sol"; diff --git a/src/aave/interfaces/IPool.sol b/src/aave/interfaces/IPool.sol index 242d464..a4ec807 100644 --- a/src/aave/interfaces/IPool.sol +++ b/src/aave/interfaces/IPool.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: AGPL-3.0 -pragma solidity ^0.8.0; +pragma solidity ^0.8.19; import { IPoolAddressesProvider } from "./IPoolAddressesProvider.sol"; import { DataTypes } from "./DataTypes.sol"; diff --git a/src/aave/interfaces/IPoolAddressesProvider.sol b/src/aave/interfaces/IPoolAddressesProvider.sol index 3a32733..34ac99b 100644 --- a/src/aave/interfaces/IPoolAddressesProvider.sol +++ b/src/aave/interfaces/IPoolAddressesProvider.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: AGPL-3.0 -pragma solidity ^0.8.0; +pragma solidity ^0.8.19; /** * @title IPoolAddressesProvider diff --git a/src/aave/interfaces/ReserveConfiguration.sol b/src/aave/interfaces/ReserveConfiguration.sol index 558e873..a018f60 100644 --- a/src/aave/interfaces/ReserveConfiguration.sol +++ b/src/aave/interfaces/ReserveConfiguration.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BUSL-1.1 -pragma solidity ^0.8.0; +pragma solidity ^0.8.19; import { Errors } from "./Errors.sol"; import { DataTypes } from "./DataTypes.sol"; diff --git a/src/balancer/BalancerWrapper.sol b/src/balancer/BalancerWrapper.sol index 3ea0e95..56c2356 100644 --- a/src/balancer/BalancerWrapper.sol +++ b/src/balancer/BalancerWrapper.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // Thanks to ultrasecr.eth -pragma solidity ^0.8.0; +pragma solidity ^0.8.19; import { IFlashLoanRecipient } from "./interfaces/IFlashLoanRecipient.sol"; import { IFlashLoaner } from "./interfaces/IFlashLoaner.sol"; @@ -11,7 +11,6 @@ import { FixedPointMathLib } from "lib/solmate/src/utils/FixedPointMathLib.sol"; import { BaseWrapper, IERC7399, ERC20 } from "../BaseWrapper.sol"; - /// @dev Balancer Flash Lender that uses Balancer Pools as source of liquidity. /// Balancer allows pushing repayments, so we override `_repayTo`. contract BalancerWrapper is BaseWrapper, IFlashLoanRecipient { @@ -19,6 +18,9 @@ contract BalancerWrapper is BaseWrapper, IFlashLoanRecipient { using Arrays for address; using FixedPointMathLib for uint256; + error NotBalancer(); + error HashMismatch(); + IFlashLoaner public immutable balancer; bytes32 private flashLoanDataHash; @@ -52,8 +54,8 @@ contract BalancerWrapper is BaseWrapper, IFlashLoanRecipient { external override { - require(msg.sender == address(balancer), "BalancerWrapper: not balancer"); - require(keccak256(params) == flashLoanDataHash, "BalancerWrapper: params hash mismatch"); + if (msg.sender != address(balancer)) revert NotBalancer(); + if (keccak256(params) != flashLoanDataHash) revert HashMismatch(); delete flashLoanDataHash; bridgeToCallback(assets[0], amounts[0], fees[0], params); diff --git a/src/balancer/interfaces/IFlashLoanRecipient.sol b/src/balancer/interfaces/IFlashLoanRecipient.sol index cd76c78..d08fd4d 100644 --- a/src/balancer/interfaces/IFlashLoanRecipient.sol +++ b/src/balancer/interfaces/IFlashLoanRecipient.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity ^0.8.0; +pragma solidity ^0.8.19; interface IFlashLoanRecipient { /** diff --git a/src/balancer/interfaces/IFlashLoaner.sol b/src/balancer/interfaces/IFlashLoaner.sol index f571c9d..346a633 100644 --- a/src/balancer/interfaces/IFlashLoaner.sol +++ b/src/balancer/interfaces/IFlashLoaner.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity ^0.8.0; +pragma solidity ^0.8.19; import { IFlashLoanRecipient } from "./IFlashLoanRecipient.sol"; import { IProtocolFeesCollector } from "./IProtocolFeesCollector.sol"; diff --git a/src/balancer/interfaces/IProtocolFeesCollector.sol b/src/balancer/interfaces/IProtocolFeesCollector.sol index 704a86a..7c99646 100644 --- a/src/balancer/interfaces/IProtocolFeesCollector.sol +++ b/src/balancer/interfaces/IProtocolFeesCollector.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity ^0.8.0; +pragma solidity ^0.8.19; interface IProtocolFeesCollector { function getFlashLoanFeePercentage() external view returns (uint256); diff --git a/src/erc3156/ERC3156Wrapper.sol b/src/erc3156/ERC3156Wrapper.sol index 0704f0c..833873e 100644 --- a/src/erc3156/ERC3156Wrapper.sol +++ b/src/erc3156/ERC3156Wrapper.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; +pragma solidity ^0.8.19; import { IERC3156FlashLender } from "lib/erc3156/contracts/interfaces/IERC3156FlashLender.sol"; import { IERC3156FlashBorrower } from "lib/erc3156/contracts/interfaces/IERC3156FlashBorrower.sol"; @@ -14,7 +14,7 @@ import { BaseWrapper, IERC7399 } from "../BaseWrapper.sol"; contract ERC3156Wrapper is BaseWrapper, IERC3156FlashBorrower { bytes32 public constant CALLBACK_SUCCESS = keccak256("ERC3156FlashBorrower.onFlashLoan"); - mapping(address => IERC3156FlashLender) public lenders; + mapping(address asset => IERC3156FlashLender lender) public lenders; /** * @param assets_ Asset contracts supported for flash lending. diff --git a/src/uniswapV3/UniswapV3Wrapper.sol b/src/uniswapV3/UniswapV3Wrapper.sol index aa3cb97..edb1727 100644 --- a/src/uniswapV3/UniswapV3Wrapper.sol +++ b/src/uniswapV3/UniswapV3Wrapper.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -// Thanks to sunnyRK and yashnaman -pragma solidity ^0.8.0; +// Thanks to sunnyRK, yashnaman & ultrasecr.eth +pragma solidity ^0.8.19; import { Registry } from "lib/registry/src/Registry.sol"; @@ -24,13 +24,13 @@ contract UniswapV3Wrapper is BaseWrapper, IUniswapV3FlashCallback { address public immutable usdc; address public immutable usdt; - /// @param registry Registry storing constructor parameters - constructor(Registry registry) { + /// @param reg Registry storing constructor parameters + constructor(Registry reg) { // @param factory_ Uniswap v3 UniswapV3Factory address // @param weth_ Weth contract used in Uniswap v3 Pairs // @param usdc_ usdc contract used in Uniswap v3 Pairs // @param usdt_ usdt contract used in Uniswap v3 Pairs - (factory, weth, usdc, usdt) = abi.decode(registry.get("UniswapV3Wrapper"), (address, address, address, address)); + (factory, weth, usdc, usdt) = abi.decode(reg.get("UniswapV3Wrapper"), (address, address, address, address)); } /** diff --git a/src/utils/Arrays.sol b/src/utils/Arrays.sol index e326d71..53fffe4 100644 --- a/src/utils/Arrays.sol +++ b/src/utils/Arrays.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-or-later // Thanks to ultrasecr.eth -pragma solidity ^0.8.0; +pragma solidity ^0.8.19; library Arrays { function toArray(uint256 n) internal pure returns (uint256[] memory arr) { diff --git a/src/utils/RevertMsgExtractor.sol b/src/utils/RevertMsgExtractor.sol index 7e190a1..7f18ab0 100644 --- a/src/utils/RevertMsgExtractor.sol +++ b/src/utils/RevertMsgExtractor.sol @@ -2,7 +2,7 @@ // Taken from // https://github.com/sushiswap/BoringSolidity/blob/441e51c0544cf2451e6116fe00515e71d7c42e2c/src/BoringBatchable.sol -pragma solidity >=0.6.0; +pragma solidity ^0.8.19; library RevertMsgExtractor { /// @dev Helper function to extract a useful revert message from a failed call. @@ -11,6 +11,7 @@ library RevertMsgExtractor { // If the _res length is less than 68, then the transaction failed silently (without a revert message) if (returnData.length < 68) return "Transaction reverted silently"; + // solhint-disable-next-line no-inline-assembly assembly { // Slice the sighash. returnData := add(returnData, 0x04) diff --git a/src/utils/TransferHelper.sol b/src/utils/TransferHelper.sol index 7a4a6fc..5fde0da 100644 --- a/src/utils/TransferHelper.sol +++ b/src/utils/TransferHelper.sol @@ -1,9 +1,9 @@ // SPDX-License-Identifier: MIT // Taken from https://github.com/Uniswap/uniswap-lib/blob/master/src/libraries/TransferHelper.sol -pragma solidity ^0.8.0; +pragma solidity ^0.8.19; import { ERC20 } from "solmate/tokens/ERC20.sol"; -import "./RevertMsgExtractor.sol"; +import { RevertMsgExtractor } from "./RevertMsgExtractor.sol"; // helper methods for interacting with ERC20 tokens and sending ETH that do not consistently return true/false // USDT is a well known token that returns nothing for its transfer, transferFrom, and approve functions @@ -16,7 +16,8 @@ library TransferHelper { /// @param value The value of the transfer function safeTransfer(address asset, address to, uint256 value) internal { (bool success, bytes memory data) = - address(asset).call(abi.encodeWithSelector(ERC20.transfer.selector, to, value)); + // solhint-disable-next-line avoid-low-level-calls + address(asset).call(abi.encodeWithSelector(ERC20.transfer.selector, to, value)); if (!(success && (data.length == 0 || abi.decode(data, (bool))))) revert(RevertMsgExtractor.getRevertMsg(data)); } } diff --git a/test/MockBorrower.sol b/test/MockBorrower.sol index ec4e6c3..c76dc23 100644 --- a/test/MockBorrower.sol +++ b/test/MockBorrower.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; +pragma solidity ^0.8.19; import "erc7399/IERC7399.sol"; From c490982bf58cf44faeb4ae29882984521d63def8 Mon Sep 17 00:00:00 2001 From: "ultrasecr.eth" <241804+ultrasecreth@users.noreply.github.com> Date: Tue, 8 Aug 2023 23:55:02 +0100 Subject: [PATCH 4/6] Deploy script --- script/Deploy.s.sol | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/script/Deploy.s.sol b/script/Deploy.s.sol index beface2..1256cda 100644 --- a/script/Deploy.s.sol +++ b/script/Deploy.s.sol @@ -2,8 +2,44 @@ pragma solidity >=0.8.19 <=0.9.0; import { BaseScript } from "./Base.s.sol"; +import { console2 } from "forge-std/console2.sol"; + +import { Registry } from "lib/registry/src/Registry.sol"; + +import { UniswapV3Wrapper } from "../src/uniswapV3/UniswapV3Wrapper.sol"; +import { AaveWrapper, IPoolAddressesProvider } from "../src/aave/AaveWrapper.sol"; +import { BalancerWrapper, IFlashLoaner } from "../src/balancer/BalancerWrapper.sol"; /// @dev See the Solidity Scripting tutorial: https://book.getfoundry.sh/tutorials/solidity-scripting contract Deploy is BaseScript { - function run() public broadcast { } + bytes32 public constant SALT = keccak256("ERC7399-wrappers"); + + address internal factory = 0x1F98431c8aD98523631AE4a59f267346ea31F984; + address internal usdc = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48; + address internal usdt = 0xdAC17F958D2ee523a2206206994597C13D831ec7; + address internal weth = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2; + address internal wbtc = 0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599; + + IFlashLoaner internal balancer = IFlashLoaner(0xBA12222222228d8Ba445958a75a0704d566BF2C8); + + IPoolAddressesProvider internal provider = IPoolAddressesProvider(0xa97684ead0e402dC232d5A977953DF7ECBaB3CDb); + + function run() public broadcast { + require(block.chainid == 42161, "Only deploy on Arbitrum"); + + Registry registry = new Registry{salt: SALT}(broadcaster); + + console2.log("Registry deployed at: %s", address(registry)); + + registry.set("UniswapV3Wrapper", abi.encode(factory, weth, usdc, usdt)); + + UniswapV3Wrapper uniswapV3Wrapper = new UniswapV3Wrapper{salt: SALT}(registry); + console2.log("UniswapV3Wrapper deployed at: %s", address(uniswapV3Wrapper)); + + BalancerWrapper balancerWrapper = new BalancerWrapper{salt: SALT}(balancer); + console2.log("BalancerWrapper deployed at: %s", address(balancerWrapper)); + + AaveWrapper aaveWrapper = new AaveWrapper{salt: SALT}(provider); + console2.log("AaveWrapper deployed at: %s", address(aaveWrapper)); + } } From a39cfc7f1a315c69a92748a074873019b63ee3d5 Mon Sep 17 00:00:00 2001 From: "ultrasecr.eth" <241804+ultrasecreth@users.noreply.github.com> Date: Tue, 8 Aug 2023 23:57:03 +0100 Subject: [PATCH 5/6] Lint 2 --- script/Deploy.s.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script/Deploy.s.sol b/script/Deploy.s.sol index 1256cda..aaed790 100644 --- a/script/Deploy.s.sol +++ b/script/Deploy.s.sol @@ -25,7 +25,7 @@ contract Deploy is BaseScript { IPoolAddressesProvider internal provider = IPoolAddressesProvider(0xa97684ead0e402dC232d5A977953DF7ECBaB3CDb); function run() public broadcast { - require(block.chainid == 42161, "Only deploy on Arbitrum"); + require(block.chainid == 42_161, "Only deploy on Arbitrum"); Registry registry = new Registry{salt: SALT}(broadcaster); From 2b93d72963f0e2fd3f1f91cb8697b220ec70222a Mon Sep 17 00:00:00 2001 From: "ultrasecr.eth" <241804+ultrasecreth@users.noreply.github.com> Date: Wed, 9 Aug 2023 00:05:28 +0100 Subject: [PATCH 6/6] Standardise errors --- src/uniswapV3/UniswapV3Wrapper.sol | 9 ++++++--- test/AaveWrapper.t.sol | 4 ++-- test/BalancerWrapper.t.sol | 4 ++-- test/UniswapV3Wrapper.t.sol | 2 +- 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/uniswapV3/UniswapV3Wrapper.sol b/src/uniswapV3/UniswapV3Wrapper.sol index edb1727..e195e5f 100644 --- a/src/uniswapV3/UniswapV3Wrapper.sol +++ b/src/uniswapV3/UniswapV3Wrapper.sol @@ -16,6 +16,9 @@ contract UniswapV3Wrapper is BaseWrapper, IUniswapV3FlashCallback { using PoolAddress for address; using { canLoan, balance } for IUniswapV3Pool; + error UnknownPool(); + error UnsupportedCurrency(address asset); + // CONSTANTS address public immutable factory; @@ -78,13 +81,13 @@ contract UniswapV3Wrapper is BaseWrapper, IUniswapV3FlashCallback { /// @inheritdoc IERC7399 function flashFee(address asset, uint256 amount) external view returns (uint256) { IUniswapV3Pool pool = cheapestPool(asset, amount); - require(address(pool) != address(0), "Unsupported currency"); + if (address(pool) == address(0)) revert UnsupportedCurrency(asset); return amount * uint256(pool.fee()) / 1e6; } function _flashLoan(address asset, uint256 amount, bytes memory data) internal override { IUniswapV3Pool pool = cheapestPool(asset, amount); - require(address(pool) != address(0), "Unsupported currency"); + if (address(pool) == address(0)) revert UnsupportedCurrency(asset); address asset0 = address(pool.token0()); address asset1 = address(pool.token1()); @@ -105,7 +108,7 @@ contract UniswapV3Wrapper is BaseWrapper, IUniswapV3FlashCallback { { (address asset, address other, uint24 feeTier, uint256 amount, bytes memory data) = abi.decode(params, (address, address, uint24, uint256, bytes)); - require(msg.sender == address(_pool(asset, other, feeTier)), "UniswapV3Wrapper: Unknown pool"); + if (msg.sender != address(_pool(asset, other, feeTier))) revert UnknownPool(); uint256 fee = fee0 > 0 ? fee0 : fee1; bridgeToCallback(asset, amount, fee, data); diff --git a/test/AaveWrapper.t.sol b/test/AaveWrapper.t.sol index 007c2e1..5273e59 100644 --- a/test/AaveWrapper.t.sol +++ b/test/AaveWrapper.t.sol @@ -68,11 +68,11 @@ contract AaveWrapperTest is PRBTest, StdCheats { } function test_executeOperation_permissions() public { - vm.expectRevert("AaveFlashLoanProvider: not pool"); + vm.expectRevert(AaveWrapper.NotPool.selector); wrapper.executeOperation({ asset: address(dai), amount: 1e18, fee: 0, initiator: address(wrapper), params: "" }); vm.prank(provider.getPool()); - vm.expectRevert("AaveFlashLoanProvider: not initiator"); + vm.expectRevert(AaveWrapper.NotInitiator.selector); wrapper.executeOperation({ asset: address(dai), amount: 1e18, fee: 0, initiator: address(0x666), params: "" }); } } diff --git a/test/BalancerWrapper.t.sol b/test/BalancerWrapper.t.sol index eab254f..cb0a3ef 100644 --- a/test/BalancerWrapper.t.sol +++ b/test/BalancerWrapper.t.sol @@ -73,7 +73,7 @@ contract BalancerWrapperTest is PRBTest, StdCheats { } function test_receiveFlashLoan_permissions() public { - vm.expectRevert("BalancerWrapper: not balancer"); + vm.expectRevert(BalancerWrapper.NotBalancer.selector); wrapper.receiveFlashLoan({ assets: address(dai).toArray(), amounts: uint256(1e18).toArray(), @@ -82,7 +82,7 @@ contract BalancerWrapperTest is PRBTest, StdCheats { }); vm.prank(address(balancer)); - vm.expectRevert("BalancerWrapper: params hash mismatch"); + vm.expectRevert(BalancerWrapper.HashMismatch.selector); wrapper.receiveFlashLoan({ assets: address(dai).toArray(), amounts: uint256(1e18).toArray(), diff --git a/test/UniswapV3Wrapper.t.sol b/test/UniswapV3Wrapper.t.sol index b869bbd..045c787 100644 --- a/test/UniswapV3Wrapper.t.sol +++ b/test/UniswapV3Wrapper.t.sol @@ -84,7 +84,7 @@ contract UniswapV3WrapperTest is PRBTest, StdCheats { } function test_uniswapV3FlashCallback_permissions() public { - vm.expectRevert("UniswapV3Wrapper: Unknown pool"); + vm.expectRevert(UniswapV3Wrapper.UnknownPool.selector); wrapper.uniswapV3FlashCallback({ fee0: 0, fee1: 0,