From 13efdb9cdbdcdc42bbd98f92a947ea0da6e3234a Mon Sep 17 00:00:00 2001 From: Olivier van den Biggelaar Date: Tue, 30 Mar 2021 12:08:11 +0100 Subject: [PATCH] Allow adapters addition/removal in ParaswapFilter --- .../infrastructure/dapp/ParaswapFilter.sol | 27 +++++++++++- test/paraswapV4.js | 41 +++++++++---------- 2 files changed, 45 insertions(+), 23 deletions(-) diff --git a/contracts/infrastructure/dapp/ParaswapFilter.sol b/contracts/infrastructure/dapp/ParaswapFilter.sol index 300cac28b..285d19adb 100644 --- a/contracts/infrastructure/dapp/ParaswapFilter.sol +++ b/contracts/infrastructure/dapp/ParaswapFilter.sol @@ -19,6 +19,7 @@ pragma experimental ABIEncoderV2; import "./BaseFilter.sol"; import "../IAuthoriser.sol"; +import "../base/Owned.sol"; import "../../modules/common/Utils.sol"; interface IParaswap { @@ -66,7 +67,7 @@ interface IParaswap { function getUniswapProxy() external view returns (address); } -contract ParaswapFilter is BaseFilter { +contract ParaswapFilter is BaseFilter, Owned { bytes4 constant internal MULTISWAP = bytes4(keccak256( "multiSwap((address,uint256,uint256,uint256,address,string,bool,(address,uint256,(address,address,uint256,bytes,uint256)[])[]))" @@ -105,6 +106,10 @@ contract ParaswapFilter is BaseFilter { bytes32 public immutable uniForkInitCode2; // linkswap bytes32 public immutable uniForkInitCode3; // defiswap + // Events + event AdapterAdded(address indexed _adapter); + event AdapterRemoved(address indexed _adapter); + constructor( address _tokenRegistry, IAuthoriser _authoriser, @@ -123,8 +128,28 @@ contract ParaswapFilter is BaseFilter { uniForkInitCode1 = _uniInitCodes[0]; uniForkInitCode2 = _uniInitCodes[1]; uniForkInitCode3 = _uniInitCodes[2]; + for(uint i = 0; i < _adapters.length; i++) { adapters[_adapters[i]] = true; + emit AdapterAdded(_adapters[i]); + } + } + + /** + * @notice Add/Remove a DEX adapter to/from the whitelist. + * @param _adapters array of DEX adapters to add to (or remove from) the whitelist + * @param _authorised array where each entry is true to add the corresponding DEX to the whitelist, false to remove it + */ + function setAuthorised(address[] calldata _adapters, bool[] calldata _authorised) external onlyOwner { + for(uint256 i = 0; i < _adapters.length; i++) { + if(adapters[_adapters[i]] != _authorised[i]) { + adapters[_adapters[i]] = _authorised[i]; + if(_authorised[i]) { + emit AdapterAdded(_adapters[i]); + } else { + emit AdapterRemoved(_adapters[i]); + } + } } } diff --git a/test/paraswapV4.js b/test/paraswapV4.js index c35791c37..9be8f7d26 100644 --- a/test/paraswapV4.js +++ b/test/paraswapV4.js @@ -73,7 +73,6 @@ contract("Paraswap Filter", (accounts) => { let uniswapV1Factory; let uniswapV1Exchanges; let uniswapV1Adapter; - let unauthorisedAdapter; let uniswapV2Factory; let initCode; let tokenA; @@ -82,6 +81,7 @@ contract("Paraswap Filter", (accounts) => { let paraswapProxy; let tokenPriceRegistry; let uniswapProxy; + let paraswapFilter; before(async () => { // Deploy test tokens @@ -122,7 +122,6 @@ contract("Paraswap Filter", (accounts) => { infrastructure, uniswapProxy.address); uniswapV1Adapter = await Uniswap.new(); - unauthorisedAdapter = await Uniswap.new(); const wlr = await paraswapWhitelist.WHITELISTED_ROLE(); await paraswapWhitelist.grantRole(wlr, uniswapV1Adapter.address); await paraswap.initializeAdapter(uniswapV1Adapter.address, web3.eth.abi.encodeParameter( @@ -147,7 +146,7 @@ contract("Paraswap Filter", (accounts) => { RECOVERY_PERIOD, LOCK_PERIOD); await registry.registerModule(module.address, ethers.utils.formatBytes32String("ArgentModule")); - const paraswapFilter = await ParaswapFilter.new( + paraswapFilter = await ParaswapFilter.new( tokenPriceRegistry.address, dappRegistry.address, uniswapProxy.address, @@ -204,7 +203,7 @@ contract("Paraswap Filter", (accounts) => { } }; - function getPath({ fromToken, toToken, fromAmount, toAmount, useUnauthorisedAdapter }) { + function getPath({ fromToken, toToken, fromAmount, toAmount }) { const routes = [{ exchange: "uniswap", percent: "100", @@ -212,20 +211,20 @@ contract("Paraswap Filter", (accounts) => { destAmount: toAmount.toString(), data: { tokenFrom: fromToken, tokenTo: toToken }, }]; - const exchanges = { uniswap: useUnauthorisedAdapter ? unauthorisedAdapter.address : uniswapV1Adapter.address }; + const exchanges = { uniswap: uniswapV1Adapter.address }; const targetExchanges = { uniswap: uniswapV1Factory.address }; return makePathes(fromToken, toToken, routes, exchanges, targetExchanges, false); } - function getMultiSwapData({ fromToken, toToken, fromAmount, toAmount, beneficiary, useUnauthorisedAdapter }) { - const path = getPath({ fromToken, toToken, fromAmount, toAmount, useUnauthorisedAdapter }); + function getMultiSwapData({ fromToken, toToken, fromAmount, toAmount, beneficiary }) { + const path = getPath({ fromToken, toToken, fromAmount, toAmount }); return paraswap.contract.methods.multiSwap({ fromToken, fromAmount, toAmount, expectedAmount: 0, beneficiary, referrer: "abc", useReduxToken: false, path }).encodeABI(); } - function getMegaSwapData({ fromToken, toToken, fromAmount, toAmount, beneficiary, useUnauthorisedAdapter }) { - const path = getPath({ fromToken, toToken, fromAmount, toAmount, useUnauthorisedAdapter }); + function getMegaSwapData({ fromToken, toToken, fromAmount, toAmount, beneficiary }) { + const path = getPath({ fromToken, toToken, fromAmount, toAmount }); return paraswap.contract.methods.megaSwap({ fromToken, fromAmount, @@ -284,7 +283,6 @@ contract("Paraswap Filter", (accounts) => { beneficiary = ZERO_ADDRESS, fromAmount = web3.utils.toWei("0.01"), toAmount = 1, - useUnauthorisedAdapter = false, errorReason = null }) { const beforeFrom = await getBalance(fromToken, wallet); @@ -302,7 +300,7 @@ contract("Paraswap Filter", (accounts) => { // token swap let swapData; if (method === "multiSwap") { - swapData = getMultiSwapData({ fromToken, toToken, fromAmount, toAmount, beneficiary, useUnauthorisedAdapter }); + swapData = getMultiSwapData({ fromToken, toToken, fromAmount, toAmount, beneficiary }); } else if (method === "simpleSwap") { swapData = getSimpleSwapData({ fromToken, toToken, fromAmount, toAmount, beneficiary }); } else if (method === "swapOnUniswap") { @@ -310,7 +308,7 @@ contract("Paraswap Filter", (accounts) => { } else if (method === "swapOnUniswapFork") { swapData = getSwapOnUniswapForkData({ fromToken, toToken, fromAmount, toAmount }); } else if (method === "megaSwap") { - swapData = getMegaSwapData({ fromToken, toToken, fromAmount, toAmount, beneficiary, useUnauthorisedAdapter }); + swapData = getMegaSwapData({ fromToken, toToken, fromAmount, toAmount, beneficiary }); } else { throw new Error("Invalid method"); } @@ -372,24 +370,23 @@ contract("Paraswap Filter", (accounts) => { await dappRegistry.addDapp(0, uniswapV1Exchanges[tokenA.address].address, ZERO_ADDRESS); }); - it("should not allow multiSwap via unauthorised adapter", async () => { + async function testUnauthorisedAdapter(method) { + await paraswapFilter.setAuthorised([uniswapV1Adapter.address], [false]); await testTrade({ - method: "multiSwap", + method, fromToken: PARASWAP_ETH_TOKEN, toToken: tokenA.address, - useUnauthorisedAdapter: true, errorReason: "TM: call not authorised" }); + await paraswapFilter.setAuthorised([uniswapV1Adapter.address], [true]); + } + + it("should not allow multiSwap via unauthorised adapter", async () => { + await testUnauthorisedAdapter("multiSwap"); }); it("should not allow megaSwap via unauthorised adapter", async () => { - await testTrade({ - method: "megaSwap", - fromToken: PARASWAP_ETH_TOKEN, - toToken: tokenA.address, - useUnauthorisedAdapter: true, - errorReason: "TM: call not authorised" - }); + await testUnauthorisedAdapter("megaSwap"); }); }); });