diff --git a/deploy/AllocatorDeploy.sol b/deploy/AllocatorDeploy.sol index a3c2cf56..eff32680 100644 --- a/deploy/AllocatorDeploy.sol +++ b/deploy/AllocatorDeploy.sol @@ -30,7 +30,7 @@ import { StableSwapper } from "src/funnels/automation/StableSwapper.sol"; import { StableDepositorUniV3 } from "src/funnels/automation/StableDepositorUniV3.sol"; import { ConduitMover } from "src/funnels/automation/ConduitMover.sol"; -import { AllocatorSharedInstance, AllocatorIlkInstance } from "./AllocatorInstances.sol"; +import { AllocatorSharedInstance, AllocatorIlkInstance, AllocatorIlkFunnelInstance } from "./AllocatorInstances.sol"; library AllocatorDeploy { @@ -59,8 +59,7 @@ library AllocatorDeploy { address owner, address roles, bytes32 ilk, - address nstJoin, - address uniV3Factory + address nstJoin ) internal returns (AllocatorIlkInstance memory ilkInstance) { address _buffer = address(new AllocatorBuffer()); ScriptTools.switchOwner(_buffer, deployer, owner); @@ -70,38 +69,51 @@ library AllocatorDeploy { ScriptTools.switchOwner(_vault, deployer, owner); ilkInstance.vault = _vault; - address _swapper = address(new Swapper(roles, ilk, _buffer)); + ilkInstance.owner = owner; + } + + // Note: owner is assumed to be the allocator proxy + function deployIlkFunnel( + address deployer, + address owner, + address roles, + bytes32 ilk, + address uniV3Factory, + address vault, + address buffer + ) internal returns (AllocatorIlkFunnelInstance memory ilkFunnelInstance) { + address _swapper = address(new Swapper(roles, ilk, buffer)); ScriptTools.switchOwner(_swapper, deployer, owner); - ilkInstance.swapper = _swapper; + ilkFunnelInstance.swapper = _swapper; - address _depositorUniV3 = address(new DepositorUniV3(roles, ilk, uniV3Factory, _buffer)); + address _depositorUniV3 = address(new DepositorUniV3(roles, ilk, uniV3Factory, buffer)); ScriptTools.switchOwner(_depositorUniV3, deployer, owner); - ilkInstance.depositorUniV3 = _depositorUniV3; + ilkFunnelInstance.depositorUniV3 = _depositorUniV3; { - address _vaultMinter = address(new VaultMinter(_vault)); + address _vaultMinter = address(new VaultMinter(vault)); ScriptTools.switchOwner(_vaultMinter, deployer, owner); - ilkInstance.vaultMinter = _vaultMinter; + ilkFunnelInstance.vaultMinter = _vaultMinter; } { address _stableSwapper = address(new StableSwapper(_swapper)); ScriptTools.switchOwner(_stableSwapper, deployer, owner); - ilkInstance.stableSwapper = _stableSwapper; + ilkFunnelInstance.stableSwapper = _stableSwapper; } { address _stableDepositorUniV3 = address(new StableDepositorUniV3(_depositorUniV3)); ScriptTools.switchOwner(_stableDepositorUniV3, deployer, owner); - ilkInstance.stableDepositorUniV3 = _stableDepositorUniV3; + ilkFunnelInstance.stableDepositorUniV3 = _stableDepositorUniV3; } { - address _conduitMover = address(new ConduitMover(ilk, _buffer)); + address _conduitMover = address(new ConduitMover(ilk, buffer)); ScriptTools.switchOwner(_conduitMover, deployer, owner); - ilkInstance.conduitMover = _conduitMover; + ilkFunnelInstance.conduitMover = _conduitMover; } - ilkInstance.owner = owner; + ilkFunnelInstance.owner = owner; } } diff --git a/deploy/AllocatorInit.sol b/deploy/AllocatorInit.sol index 6d056b1b..08c3d8d7 100644 --- a/deploy/AllocatorInit.sol +++ b/deploy/AllocatorInit.sol @@ -18,7 +18,7 @@ pragma solidity >=0.8.0; import { ScriptTools } from "dss-test/ScriptTools.sol"; import { DssInstance } from "dss-test/MCD.sol"; -import { AllocatorSharedInstance, AllocatorIlkInstance } from "./AllocatorInstances.sol"; +import { AllocatorSharedInstance, AllocatorIlkInstance, AllocatorIlkFunnelInstance } from "./AllocatorInstances.sol"; interface WardsLike { function rely(address) external; @@ -134,6 +134,12 @@ struct AllocatorIlkConfig { uint256 maxLine; uint256 ttl; address allocatorProxy; + address ilkRegistry; +} + +struct AllocatorIlkFunnelConfig { + bytes32 ilk; + address allocatorProxy; uint8 facilitatorRole; uint8 automationRole; address[] facilitators; @@ -143,7 +149,6 @@ struct AllocatorIlkConfig { address[] conduitMoverKeepers; address[] swapTokens; address[] depositTokens; - address ilkRegistry; address uniV3Factory; } @@ -172,6 +177,7 @@ library AllocatorInit { dss.chainlog.setAddress("ALLOCATOR_REGISTRY", sharedInstance.registry); } + // Please note this should be executed by the pause proxy function initIlk( DssInstance memory dss, AllocatorSharedInstance memory sharedInstance, @@ -187,23 +193,6 @@ library AllocatorInit { require(VaultLike(ilkInstance.vault).vat() == address(dss.vat), "AllocatorInit/vault-vat-mismatch"); // Once nstJoin is in the chainlog and adapted to dss-test should also check against it - require(SwapperLike(ilkInstance.swapper).roles() == sharedInstance.roles, "AllocatorInit/swapper-roles-mismatch"); - require(SwapperLike(ilkInstance.swapper).ilk() == ilk, "AllocatorInit/swapper-ilk-mismatch"); - require(SwapperLike(ilkInstance.swapper).buffer() == ilkInstance.buffer, "AllocatorInit/swapper-buffer-mismatch"); - - require(DepositorUniV3Like(ilkInstance.depositorUniV3).roles() == sharedInstance.roles, "AllocatorInit/depositorUniV3-roles-mismatch"); - require(DepositorUniV3Like(ilkInstance.depositorUniV3).ilk() == ilk, "AllocatorInit/depositorUniV3-ilk-mismatch"); - require(DepositorUniV3Like(ilkInstance.depositorUniV3).uniV3Factory() == cfg.uniV3Factory, "AllocatorInit/depositorUniV3-uniV3Factory-mismatch"); - require(DepositorUniV3Like(ilkInstance.depositorUniV3).buffer() == ilkInstance.buffer, "AllocatorInit/depositorUniV3-buffer-mismatch"); - - require(VaultMinterLike(ilkInstance.vaultMinter).vault() == ilkInstance.vault, "AllocatorInit/vaultMinter-vault-mismatch"); - - require(StableSwapperLike(ilkInstance.stableSwapper).swapper() == ilkInstance.swapper, "AllocatorInit/stableSwapper-swapper-mismatch"); - require(StableDepositorUniV3Like(ilkInstance.stableDepositorUniV3).depositor() == ilkInstance.depositorUniV3, "AllocatorInit/stableDepositorUniV3-depositorUniV3-mismatch"); - - require(ConduitMoverLike(ilkInstance.conduitMover).ilk() == ilk, "AllocatorInit/conduitMover-ilk-mismatch"); - require(ConduitMoverLike(ilkInstance.conduitMover).buffer() == ilkInstance.buffer, "AllocatorInit/conduitMover-buffer-mismatch"); - // Onboard the ilk dss.vat.init(ilk); dss.jug.init(ilk); @@ -228,94 +217,114 @@ library AllocatorInit { VaultLike(ilkInstance.vault).file("jug", address(dss.jug)); - // Allow vault and funnels to pull funds from the buffer + // Allow vault to pull funds from the buffer BufferLike(ilkInstance.buffer).approve(VaultLike(ilkInstance.vault).nst(), ilkInstance.vault, type(uint256).max); + + // Set the allocator proxy as the ilk admin instead of the Pause Proxy + RolesLike(sharedInstance.roles).setIlkAdmin(ilk, cfg.allocatorProxy); + + // Move ownership of the ilk contracts to the allocator proxy + ScriptTools.switchOwner(ilkInstance.vault, ilkInstance.owner, cfg.allocatorProxy); + ScriptTools.switchOwner(ilkInstance.buffer, ilkInstance.owner, cfg.allocatorProxy); + + // Add allocator-specific contracts to changelog + string memory ilkString = ScriptTools.ilkToChainlogFormat(ilk); + dss.chainlog.setAddress(ScriptTools.stringToBytes32(string(abi.encodePacked(ilkString, "_VAULT"))), ilkInstance.vault); + dss.chainlog.setAddress(ScriptTools.stringToBytes32(string(abi.encodePacked(ilkString, "_BUFFER"))), ilkInstance.buffer); + dss.chainlog.setAddress(ScriptTools.stringToBytes32(string(abi.encodePacked("PIP_", ilkString))), sharedInstance.oracle); + + // Add to ilk registry + IlkRegistryLike(cfg.ilkRegistry).put({ + _ilk : ilk, + _join : address(0), + _gem : address(0), + _dec : 0, + _class : 5, // RWAs are class 3, D3Ms and Teleport are class 4 + _pip : sharedInstance.oracle, + _xlip : address(0), + _name : bytes32ToStr(ilk), + _symbol : bytes32ToStr(ilk) + }); + } + + // Please note this should be executed by the allocator proxy + function initIlkFunnel( + AllocatorSharedInstance memory sharedInstance, + AllocatorIlkInstance memory ilkInstance, + AllocatorIlkFunnelInstance memory ilkFunnelInstance, + AllocatorIlkFunnelConfig memory cfg + ) internal { + bytes32 ilk = cfg.ilk; + + require(SwapperLike(ilkFunnelInstance.swapper).roles() == sharedInstance.roles, "AllocatorInit/swapper-roles-mismatch"); + require(SwapperLike(ilkFunnelInstance.swapper).ilk() == ilk, "AllocatorInit/swapper-ilk-mismatch"); + require(SwapperLike(ilkFunnelInstance.swapper).buffer() == ilkInstance.buffer, "AllocatorInit/swapper-buffer-mismatch"); + + require(DepositorUniV3Like(ilkFunnelInstance.depositorUniV3).roles() == sharedInstance.roles, "AllocatorInit/depositorUniV3-roles-mismatch"); + require(DepositorUniV3Like(ilkFunnelInstance.depositorUniV3).ilk() == ilk, "AllocatorInit/depositorUniV3-ilk-mismatch"); + require(DepositorUniV3Like(ilkFunnelInstance.depositorUniV3).uniV3Factory() == cfg.uniV3Factory, "AllocatorInit/depositorUniV3-uniV3Factory-mismatch"); + require(DepositorUniV3Like(ilkFunnelInstance.depositorUniV3).buffer() == ilkInstance.buffer, "AllocatorInit/depositorUniV3-buffer-mismatch"); + + require(VaultMinterLike(ilkFunnelInstance.vaultMinter).vault() == ilkInstance.vault, "AllocatorInit/vaultMinter-vault-mismatch"); + + require(StableSwapperLike(ilkFunnelInstance.stableSwapper).swapper() == ilkFunnelInstance.swapper, "AllocatorInit/stableSwapper-swapper-mismatch"); + require(StableDepositorUniV3Like(ilkFunnelInstance.stableDepositorUniV3).depositor() == ilkFunnelInstance.depositorUniV3, "AllocatorInit/stableDepositorUniV3-depositorUniV3-mismatch"); + + require(ConduitMoverLike(ilkFunnelInstance.conduitMover).ilk() == ilk, "AllocatorInit/conduitMover-ilk-mismatch"); + require(ConduitMoverLike(ilkFunnelInstance.conduitMover).buffer() == ilkInstance.buffer, "AllocatorInit/conduitMover-buffer-mismatch"); + + // Allow vault and funnels to pull funds from the buffer for(uint256 i = 0; i < cfg.swapTokens.length; i++) { - BufferLike(ilkInstance.buffer).approve(cfg.swapTokens[i], ilkInstance.swapper, type(uint256).max); + BufferLike(ilkInstance.buffer).approve(cfg.swapTokens[i], ilkFunnelInstance.swapper, type(uint256).max); } for(uint256 i = 0; i < cfg.depositTokens.length; i++) { - BufferLike(ilkInstance.buffer).approve(cfg.depositTokens[i], ilkInstance.depositorUniV3, type(uint256).max); + BufferLike(ilkInstance.buffer).approve(cfg.depositTokens[i], ilkFunnelInstance.depositorUniV3, type(uint256).max); } - // Set the pause proxy temporarily as ilk admin so we can set all the roles below - RolesLike(sharedInstance.roles).setIlkAdmin(ilk, ilkInstance.owner); - // Allow the facilitators to operate on the vault and funnels directly for(uint256 i = 0; i < cfg.facilitators.length; i++) { RolesLike(sharedInstance.roles).setUserRole(ilk, cfg.facilitators[i], cfg.facilitatorRole, true); } - RolesLike(sharedInstance.roles).setRoleAction(ilk, cfg.facilitatorRole, ilkInstance.vault, VaultLike.draw.selector, true); - RolesLike(sharedInstance.roles).setRoleAction(ilk, cfg.facilitatorRole, ilkInstance.vault, VaultLike.wipe.selector, true); - RolesLike(sharedInstance.roles).setRoleAction(ilk, cfg.facilitatorRole, ilkInstance.swapper, SwapperLike.swap.selector, true); - RolesLike(sharedInstance.roles).setRoleAction(ilk, cfg.facilitatorRole, ilkInstance.depositorUniV3, DepositorUniV3Like.deposit.selector, true); - RolesLike(sharedInstance.roles).setRoleAction(ilk, cfg.facilitatorRole, ilkInstance.depositorUniV3, DepositorUniV3Like.withdraw.selector, true); - RolesLike(sharedInstance.roles).setRoleAction(ilk, cfg.facilitatorRole, ilkInstance.depositorUniV3, DepositorUniV3Like.collect.selector, true); + RolesLike(sharedInstance.roles).setRoleAction(ilk, cfg.facilitatorRole, ilkInstance.vault, VaultLike.draw.selector, true); + RolesLike(sharedInstance.roles).setRoleAction(ilk, cfg.facilitatorRole, ilkInstance.vault, VaultLike.wipe.selector, true); + RolesLike(sharedInstance.roles).setRoleAction(ilk, cfg.facilitatorRole, ilkFunnelInstance.swapper, SwapperLike.swap.selector, true); + RolesLike(sharedInstance.roles).setRoleAction(ilk, cfg.facilitatorRole, ilkFunnelInstance.depositorUniV3, DepositorUniV3Like.deposit.selector, true); + RolesLike(sharedInstance.roles).setRoleAction(ilk, cfg.facilitatorRole, ilkFunnelInstance.depositorUniV3, DepositorUniV3Like.withdraw.selector, true); + RolesLike(sharedInstance.roles).setRoleAction(ilk, cfg.facilitatorRole, ilkFunnelInstance.depositorUniV3, DepositorUniV3Like.collect.selector, true); // Allow the automation contracts to operate on the funnels - RolesLike(sharedInstance.roles).setUserRole(ilk, ilkInstance.vaultMinter, cfg.automationRole, true); - RolesLike(sharedInstance.roles).setUserRole(ilk, ilkInstance.stableSwapper, cfg.automationRole, true); - RolesLike(sharedInstance.roles).setUserRole(ilk, ilkInstance.stableDepositorUniV3, cfg.automationRole, true); + RolesLike(sharedInstance.roles).setUserRole(ilk, ilkFunnelInstance.vaultMinter, cfg.automationRole, true); + RolesLike(sharedInstance.roles).setUserRole(ilk, ilkFunnelInstance.stableSwapper, cfg.automationRole, true); + RolesLike(sharedInstance.roles).setUserRole(ilk, ilkFunnelInstance.stableDepositorUniV3, cfg.automationRole, true); - RolesLike(sharedInstance.roles).setRoleAction(ilk, cfg.automationRole, ilkInstance.vault, VaultLike.draw.selector, true); - RolesLike(sharedInstance.roles).setRoleAction(ilk, cfg.automationRole, ilkInstance.vault, VaultLike.wipe.selector, true); - RolesLike(sharedInstance.roles).setRoleAction(ilk, cfg.automationRole, ilkInstance.swapper, SwapperLike.swap.selector, true); - RolesLike(sharedInstance.roles).setRoleAction(ilk, cfg.automationRole, ilkInstance.depositorUniV3, DepositorUniV3Like.deposit.selector, true); - RolesLike(sharedInstance.roles).setRoleAction(ilk, cfg.automationRole, ilkInstance.depositorUniV3, DepositorUniV3Like.withdraw.selector, true); - RolesLike(sharedInstance.roles).setRoleAction(ilk, cfg.automationRole, ilkInstance.depositorUniV3, DepositorUniV3Like.collect.selector, true); - - // Set the allocator proxy as the ilk admin instead of the Pause Proxy - RolesLike(sharedInstance.roles).setIlkAdmin(ilk, cfg.allocatorProxy); + RolesLike(sharedInstance.roles).setRoleAction(ilk, cfg.automationRole, ilkInstance.vault, VaultLike.draw.selector, true); + RolesLike(sharedInstance.roles).setRoleAction(ilk, cfg.automationRole, ilkInstance.vault, VaultLike.wipe.selector, true); + RolesLike(sharedInstance.roles).setRoleAction(ilk, cfg.automationRole, ilkFunnelInstance.swapper, SwapperLike.swap.selector, true); + RolesLike(sharedInstance.roles).setRoleAction(ilk, cfg.automationRole, ilkFunnelInstance.depositorUniV3, DepositorUniV3Like.deposit.selector, true); + RolesLike(sharedInstance.roles).setRoleAction(ilk, cfg.automationRole, ilkFunnelInstance.depositorUniV3, DepositorUniV3Like.withdraw.selector, true); + RolesLike(sharedInstance.roles).setRoleAction(ilk, cfg.automationRole, ilkFunnelInstance.depositorUniV3, DepositorUniV3Like.collect.selector, true); // Allow facilitator to set configurations in the automation contracts for(uint256 i = 0; i < cfg.facilitators.length; i++) { - WardsLike(ilkInstance.vaultMinter).rely(cfg.facilitators[i]); - WardsLike(ilkInstance.stableSwapper).rely(cfg.facilitators[i]); - WardsLike(ilkInstance.stableDepositorUniV3).rely(cfg.facilitators[i]); - WardsLike(ilkInstance.conduitMover).rely(cfg.facilitators[i]); + WardsLike(ilkFunnelInstance.vaultMinter).rely(cfg.facilitators[i]); + WardsLike(ilkFunnelInstance.stableSwapper).rely(cfg.facilitators[i]); + WardsLike(ilkFunnelInstance.stableDepositorUniV3).rely(cfg.facilitators[i]); + WardsLike(ilkFunnelInstance.conduitMover).rely(cfg.facilitators[i]); } // Add keepers to the automation contracts for(uint256 i = 0; i < cfg.vaultMinterKeepers.length; i++) { - KissLike(ilkInstance.vaultMinter).kiss(cfg.vaultMinterKeepers[i]); + KissLike(ilkFunnelInstance.vaultMinter).kiss(cfg.vaultMinterKeepers[i]); } for(uint256 i = 0; i < cfg.stableSwapperKeepers.length; i++) { - KissLike(ilkInstance.stableSwapper).kiss(cfg.stableSwapperKeepers[i]); + KissLike(ilkFunnelInstance.stableSwapper).kiss(cfg.stableSwapperKeepers[i]); } for(uint256 i = 0; i < cfg.stableDepositorUniV3Keepers.length; i++) { - KissLike(ilkInstance.stableDepositorUniV3).kiss(cfg.stableDepositorUniV3Keepers[i]); + KissLike(ilkFunnelInstance.stableDepositorUniV3).kiss(cfg.stableDepositorUniV3Keepers[i]); } for(uint256 i = 0; i < cfg.conduitMoverKeepers.length; i++) { - KissLike(ilkInstance.conduitMover).kiss(cfg.conduitMoverKeepers[i]); + KissLike(ilkFunnelInstance.conduitMover).kiss(cfg.conduitMoverKeepers[i]); } - - // Move ownership of the ilk contracts to the allocator proxy - ScriptTools.switchOwner(ilkInstance.vault, ilkInstance.owner, cfg.allocatorProxy); - ScriptTools.switchOwner(ilkInstance.buffer, ilkInstance.owner, cfg.allocatorProxy); - ScriptTools.switchOwner(ilkInstance.swapper, ilkInstance.owner, cfg.allocatorProxy); - ScriptTools.switchOwner(ilkInstance.depositorUniV3, ilkInstance.owner, cfg.allocatorProxy); - ScriptTools.switchOwner(ilkInstance.vaultMinter, ilkInstance.owner, cfg.allocatorProxy); - ScriptTools.switchOwner(ilkInstance.stableSwapper, ilkInstance.owner, cfg.allocatorProxy); - ScriptTools.switchOwner(ilkInstance.stableDepositorUniV3, ilkInstance.owner, cfg.allocatorProxy); - ScriptTools.switchOwner(ilkInstance.conduitMover, ilkInstance.owner, cfg.allocatorProxy); - - // Add allocator-specific contracts to changelog - string memory ilkString = ScriptTools.ilkToChainlogFormat(ilk); - dss.chainlog.setAddress(ScriptTools.stringToBytes32(string(abi.encodePacked(ilkString, "_VAULT"))), ilkInstance.vault); - dss.chainlog.setAddress(ScriptTools.stringToBytes32(string(abi.encodePacked(ilkString, "_BUFFER"))), ilkInstance.buffer); - dss.chainlog.setAddress(ScriptTools.stringToBytes32(string(abi.encodePacked("PIP_", ilkString))), sharedInstance.oracle); - - // Add to ilk registry - IlkRegistryLike(cfg.ilkRegistry).put({ - _ilk : ilk, - _join : address(0), - _gem : address(0), - _dec : 0, - _class : 5, // RWAs are class 3, D3Ms and Teleport are class 4 - _pip : sharedInstance.oracle, - _xlip : address(0), - _name : bytes32ToStr(ilk), - _symbol : bytes32ToStr(ilk) - }); } } diff --git a/deploy/AllocatorInstances.sol b/deploy/AllocatorInstances.sol index c3bd633e..092db88c 100644 --- a/deploy/AllocatorInstances.sol +++ b/deploy/AllocatorInstances.sol @@ -26,6 +26,10 @@ struct AllocatorIlkInstance { address owner; address vault; address buffer; +} + +struct AllocatorIlkFunnelInstance { + address owner; address swapper; address depositorUniV3; address vaultMinter; diff --git a/test/integration/Deployment.t.sol b/test/integration/Deployment.t.sol index 5770e1a1..35379b84 100644 --- a/test/integration/Deployment.t.sol +++ b/test/integration/Deployment.t.sol @@ -18,9 +18,9 @@ pragma solidity ^0.8.16; import "dss-test/DssTest.sol"; -import { AllocatorSharedInstance, AllocatorIlkInstance } from "deploy/AllocatorInstances.sol"; +import { AllocatorSharedInstance, AllocatorIlkInstance, AllocatorIlkFunnelInstance } from "deploy/AllocatorInstances.sol"; import { AllocatorDeploy } from "deploy/AllocatorDeploy.sol"; -import { AllocatorInit, AllocatorIlkConfig } from "deploy/AllocatorInit.sol"; +import { AllocatorInit, AllocatorIlkConfig, AllocatorIlkFunnelConfig } from "deploy/AllocatorInit.sol"; import { SwapperCalleeUniV3 } from "src/funnels/callees/SwapperCalleeUniV3.sol"; @@ -111,6 +111,7 @@ contract DeploymentTest is DssTest { // storage to be initiated on setup AllocatorSharedInstance sharedInst; AllocatorIlkInstance ilkInst; + AllocatorIlkFunnelInstance ilkFunnelInst; bytes usdcDaiPath; bytes daiUsdcPath; @@ -139,8 +140,16 @@ contract DeploymentTest is DssTest { owner : PAUSE_PROXY, roles : sharedInst.roles, ilk : ILK, - nstJoin : nstJoin, - uniV3Factory : UNIV3_FACTORY + nstJoin : nstJoin + }); + ilkFunnelInst = AllocatorDeploy.deployIlkFunnel({ + deployer : address(this), + owner : allocatorProxy, + roles : sharedInst.roles, + ilk : ILK, + uniV3Factory : UNIV3_FACTORY, + vault : ilkInst.vault, + buffer : ilkInst.buffer }); // Deploy conduits (assumed to be done separately than the current allocator ilkInst deploy) @@ -186,6 +195,17 @@ contract DeploymentTest is DssTest { gap : 10_000_000 * RAD, ttl : 1 days, allocatorProxy : allocatorProxy, + ilkRegistry : ILK_REGISTRY + }); + + AllocatorInit.initIlk(dss, sharedInst, ilkInst, cfg); + vm.stopPrank(); + + // Init conduits (assumed to be done separately than the current allocator ilkInst init) + vm.startPrank(allocatorProxy); + AllocatorIlkFunnelConfig memory funnelCfg = AllocatorIlkFunnelConfig({ + ilk : ILK, + allocatorProxy : allocatorProxy, facilitatorRole : facilitatorRole, automationRole : automationRole, facilitators : facilitators, @@ -195,16 +215,11 @@ contract DeploymentTest is DssTest { conduitMoverKeepers : conduitMoverKeepers, swapTokens : swapTokens, depositTokens : depositTokens, - ilkRegistry : ILK_REGISTRY, uniV3Factory : UNIV3_FACTORY }); + AllocatorInit.initIlkFunnel(sharedInst, ilkInst, ilkFunnelInst, funnelCfg); - AllocatorInit.initIlk(dss, sharedInst, ilkInst, cfg); - vm.stopPrank(); - - // Init conduits (assumed to be done separately than the current allocator ilkInst init) - vm.startPrank(allocatorProxy); - AllocatorRoles(sharedInst.roles).setUserRole(ILK, address(ilkInst.conduitMover), automationRole, true); + AllocatorRoles(sharedInst.roles).setUserRole(ILK, address(ilkFunnelInst.conduitMover), automationRole, true); AllocatorRoles(sharedInst.roles).setRoleAction(ILK, automationRole, conduit1, AllocatorConduitMock.deposit.selector, true); AllocatorRoles(sharedInst.roles).setRoleAction(ILK, automationRole, conduit1, AllocatorConduitMock.withdraw.selector, true); @@ -261,48 +276,48 @@ contract DeploymentTest is DssTest { assertEq(AllocatorRegistry(sharedInst.registry).buffers(ILK), ilkInst.buffer); assertEq(address(AllocatorVault(ilkInst.vault).jug()), address(dss.jug)); - assertEq(GemLike(nst).allowance(ilkInst.buffer, ilkInst.vault), type(uint256).max); - assertEq(GemLike(address(dss.dai)).allowance(ilkInst.buffer, ilkInst.swapper), type(uint256).max); - assertEq(GemLike(address(dss.dai)).allowance(ilkInst.buffer, ilkInst.depositorUniV3), type(uint256).max); - assertEq(GemLike(USDC).allowance(ilkInst.buffer, ilkInst.depositorUniV3), type(uint256).max); + assertEq(GemLike(nst).allowance(ilkInst.buffer, ilkInst.vault), type(uint256).max); + assertEq(GemLike(address(dss.dai)).allowance(ilkInst.buffer, ilkFunnelInst.swapper), type(uint256).max); + assertEq(GemLike(address(dss.dai)).allowance(ilkInst.buffer, ilkFunnelInst.depositorUniV3), type(uint256).max); + assertEq(GemLike(USDC).allowance(ilkInst.buffer, ilkFunnelInst.depositorUniV3), type(uint256).max); assertEq(AllocatorRoles(sharedInst.roles).ilkAdmins(ILK), allocatorProxy); assertEq(AllocatorRoles(sharedInst.roles).hasUserRole(ILK, facilitator1, facilitatorRole), true); assertEq(AllocatorRoles(sharedInst.roles).hasUserRole(ILK, facilitator2, facilitatorRole), true); - assertEq(AllocatorRoles(sharedInst.roles).hasActionRole(ILK, ilkInst.vault, AllocatorVault.draw.selector, facilitatorRole), true); - assertEq(AllocatorRoles(sharedInst.roles).hasActionRole(ILK, ilkInst.vault, AllocatorVault.wipe.selector, facilitatorRole), true); - assertEq(AllocatorRoles(sharedInst.roles).hasActionRole(ILK, ilkInst.swapper, Swapper.swap.selector, facilitatorRole), true); - assertEq(AllocatorRoles(sharedInst.roles).hasActionRole(ILK, ilkInst.depositorUniV3, DepositorUniV3.deposit.selector, facilitatorRole), true); - assertEq(AllocatorRoles(sharedInst.roles).hasActionRole(ILK, ilkInst.depositorUniV3, DepositorUniV3.withdraw.selector, facilitatorRole), true); - assertEq(AllocatorRoles(sharedInst.roles).hasActionRole(ILK, ilkInst.depositorUniV3, DepositorUniV3.collect.selector, facilitatorRole), true); - - assertEq(AllocatorRoles(sharedInst.roles).hasUserRole(ILK, ilkInst.stableSwapper, automationRole), true); - assertEq(AllocatorRoles(sharedInst.roles).hasUserRole(ILK, ilkInst.stableDepositorUniV3, automationRole), true); - - assertEq(AllocatorRoles(sharedInst.roles).hasActionRole(ILK, ilkInst.swapper, Swapper.swap.selector, automationRole), true); - assertEq(AllocatorRoles(sharedInst.roles).hasActionRole(ILK, ilkInst.depositorUniV3, DepositorUniV3.deposit.selector, automationRole), true); - assertEq(AllocatorRoles(sharedInst.roles).hasActionRole(ILK, ilkInst.depositorUniV3, DepositorUniV3.withdraw.selector, automationRole), true); - assertEq(AllocatorRoles(sharedInst.roles).hasActionRole(ILK, ilkInst.depositorUniV3, DepositorUniV3.collect.selector, automationRole), true); - - assertEq(WardsLike(ilkInst.vaultMinter).wards(facilitator1), 1); - assertEq(WardsLike(ilkInst.vaultMinter).wards(facilitator2), 1); - assertEq(WardsLike(ilkInst.stableSwapper).wards(facilitator1), 1); - assertEq(WardsLike(ilkInst.stableSwapper).wards(facilitator2), 1); - assertEq(WardsLike(ilkInst.stableDepositorUniV3).wards(facilitator1), 1); - assertEq(WardsLike(ilkInst.stableDepositorUniV3).wards(facilitator2), 1); - assertEq(WardsLike(ilkInst.conduitMover).wards(facilitator1), 1); - assertEq(WardsLike(ilkInst.conduitMover).wards(facilitator2), 1); - - assertEq(VaultMinter(ilkInst.vaultMinter).buds(vaultMinterKeeper1), 1); - assertEq(VaultMinter(ilkInst.vaultMinter).buds(vaultMinterKeeper2), 1); - assertEq(StableSwapper(ilkInst.stableSwapper).buds(stableSwapperKeeper1), 1); - assertEq(StableSwapper(ilkInst.stableSwapper).buds(stableSwapperKeeper2), 1); - assertEq(StableDepositorUniV3(ilkInst.stableDepositorUniV3).buds(stableDepositorUniV3Keeper1), 1); - assertEq(StableDepositorUniV3(ilkInst.stableDepositorUniV3).buds(stableDepositorUniV3Keeper2), 1); - assertEq(ConduitMover(ilkInst.conduitMover).buds(conduitMoverKeeper1), 1); - assertEq(ConduitMover(ilkInst.conduitMover).buds(conduitMoverKeeper2), 1); + assertEq(AllocatorRoles(sharedInst.roles).hasActionRole(ILK, ilkInst.vault, AllocatorVault.draw.selector, facilitatorRole), true); + assertEq(AllocatorRoles(sharedInst.roles).hasActionRole(ILK, ilkInst.vault, AllocatorVault.wipe.selector, facilitatorRole), true); + assertEq(AllocatorRoles(sharedInst.roles).hasActionRole(ILK, ilkFunnelInst.swapper, Swapper.swap.selector, facilitatorRole), true); + assertEq(AllocatorRoles(sharedInst.roles).hasActionRole(ILK, ilkFunnelInst.depositorUniV3, DepositorUniV3.deposit.selector, facilitatorRole), true); + assertEq(AllocatorRoles(sharedInst.roles).hasActionRole(ILK, ilkFunnelInst.depositorUniV3, DepositorUniV3.withdraw.selector, facilitatorRole), true); + assertEq(AllocatorRoles(sharedInst.roles).hasActionRole(ILK, ilkFunnelInst.depositorUniV3, DepositorUniV3.collect.selector, facilitatorRole), true); + + assertEq(AllocatorRoles(sharedInst.roles).hasUserRole(ILK, ilkFunnelInst.stableSwapper, automationRole), true); + assertEq(AllocatorRoles(sharedInst.roles).hasUserRole(ILK, ilkFunnelInst.stableDepositorUniV3, automationRole), true); + + assertEq(AllocatorRoles(sharedInst.roles).hasActionRole(ILK, ilkFunnelInst.swapper, Swapper.swap.selector, automationRole), true); + assertEq(AllocatorRoles(sharedInst.roles).hasActionRole(ILK, ilkFunnelInst.depositorUniV3, DepositorUniV3.deposit.selector, automationRole), true); + assertEq(AllocatorRoles(sharedInst.roles).hasActionRole(ILK, ilkFunnelInst.depositorUniV3, DepositorUniV3.withdraw.selector, automationRole), true); + assertEq(AllocatorRoles(sharedInst.roles).hasActionRole(ILK, ilkFunnelInst.depositorUniV3, DepositorUniV3.collect.selector, automationRole), true); + + assertEq(WardsLike(ilkFunnelInst.vaultMinter).wards(facilitator1), 1); + assertEq(WardsLike(ilkFunnelInst.vaultMinter).wards(facilitator2), 1); + assertEq(WardsLike(ilkFunnelInst.stableSwapper).wards(facilitator1), 1); + assertEq(WardsLike(ilkFunnelInst.stableSwapper).wards(facilitator2), 1); + assertEq(WardsLike(ilkFunnelInst.stableDepositorUniV3).wards(facilitator1), 1); + assertEq(WardsLike(ilkFunnelInst.stableDepositorUniV3).wards(facilitator2), 1); + assertEq(WardsLike(ilkFunnelInst.conduitMover).wards(facilitator1), 1); + assertEq(WardsLike(ilkFunnelInst.conduitMover).wards(facilitator2), 1); + + assertEq(VaultMinter(ilkFunnelInst.vaultMinter).buds(vaultMinterKeeper1), 1); + assertEq(VaultMinter(ilkFunnelInst.vaultMinter).buds(vaultMinterKeeper2), 1); + assertEq(StableSwapper(ilkFunnelInst.stableSwapper).buds(stableSwapperKeeper1), 1); + assertEq(StableSwapper(ilkFunnelInst.stableSwapper).buds(stableSwapperKeeper2), 1); + assertEq(StableDepositorUniV3(ilkFunnelInst.stableDepositorUniV3).buds(stableDepositorUniV3Keeper1), 1); + assertEq(StableDepositorUniV3(ilkFunnelInst.stableDepositorUniV3).buds(stableDepositorUniV3Keeper2), 1); + assertEq(ConduitMover(ilkFunnelInst.conduitMover).buds(conduitMoverKeeper1), 1); + assertEq(ConduitMover(ilkFunnelInst.conduitMover).buds(conduitMoverKeeper2), 1); assertEq(WardsLike(ilkInst.vault).wards(PAUSE_PROXY), 0); assertEq(WardsLike(ilkInst.vault).wards(allocatorProxy), 1); @@ -310,23 +325,23 @@ contract DeploymentTest is DssTest { assertEq(WardsLike(ilkInst.buffer).wards(PAUSE_PROXY), 0); assertEq(WardsLike(ilkInst.buffer).wards(allocatorProxy), 1); - assertEq(WardsLike(ilkInst.swapper).wards(PAUSE_PROXY), 0); - assertEq(WardsLike(ilkInst.swapper).wards(allocatorProxy), 1); + assertEq(WardsLike(ilkFunnelInst.swapper).wards(PAUSE_PROXY), 0); + assertEq(WardsLike(ilkFunnelInst.swapper).wards(allocatorProxy), 1); - assertEq(WardsLike(ilkInst.depositorUniV3).wards(PAUSE_PROXY), 0); - assertEq(WardsLike(ilkInst.depositorUniV3).wards(allocatorProxy), 1); + assertEq(WardsLike(ilkFunnelInst.depositorUniV3).wards(PAUSE_PROXY), 0); + assertEq(WardsLike(ilkFunnelInst.depositorUniV3).wards(allocatorProxy), 1); - assertEq(WardsLike(ilkInst.vaultMinter).wards(PAUSE_PROXY), 0); - assertEq(WardsLike(ilkInst.vaultMinter).wards(allocatorProxy), 1); + assertEq(WardsLike(ilkFunnelInst.vaultMinter).wards(PAUSE_PROXY), 0); + assertEq(WardsLike(ilkFunnelInst.vaultMinter).wards(allocatorProxy), 1); - assertEq(WardsLike(ilkInst.stableSwapper).wards(PAUSE_PROXY), 0); - assertEq(WardsLike(ilkInst.stableSwapper).wards(allocatorProxy), 1); + assertEq(WardsLike(ilkFunnelInst.stableSwapper).wards(PAUSE_PROXY), 0); + assertEq(WardsLike(ilkFunnelInst.stableSwapper).wards(allocatorProxy), 1); - assertEq(WardsLike(ilkInst.stableDepositorUniV3).wards(PAUSE_PROXY), 0); - assertEq(WardsLike(ilkInst.stableDepositorUniV3).wards(allocatorProxy), 1); + assertEq(WardsLike(ilkFunnelInst.stableDepositorUniV3).wards(PAUSE_PROXY), 0); + assertEq(WardsLike(ilkFunnelInst.stableDepositorUniV3).wards(allocatorProxy), 1); - assertEq(WardsLike(ilkInst.conduitMover).wards(PAUSE_PROXY), 0); - assertEq(WardsLike(ilkInst.conduitMover).wards(allocatorProxy), 1); + assertEq(WardsLike(ilkFunnelInst.conduitMover).wards(PAUSE_PROXY), 0); + assertEq(WardsLike(ilkFunnelInst.conduitMover).wards(allocatorProxy), 1); assertEq(ChainlogLike(LOG).getAddress("ILK_A_VAULT"), ilkInst.vault); assertEq(ChainlogLike(LOG).getAddress("ILK_A_BUFFER"), ilkInst.buffer); @@ -354,11 +369,11 @@ contract DeploymentTest is DssTest { function testVaultDrawWipeFromFromKeeper() public { emulateSpell(); - vm.prank(facilitator1); VaultMinter(ilkInst.vaultMinter).setConfig(1, 1 hours, uint96(1_000 * WAD)); - vm.prank(vaultMinterKeeper1); VaultMinter(ilkInst.vaultMinter).draw(); + vm.prank(facilitator1); VaultMinter(ilkFunnelInst.vaultMinter).setConfig(1, 1 hours, uint96(1_000 * WAD)); + vm.prank(vaultMinterKeeper1); VaultMinter(ilkFunnelInst.vaultMinter).draw(); - vm.prank(facilitator1); VaultMinter(ilkInst.vaultMinter).setConfig(-1, 1 hours, uint96(1_000 * WAD)); - vm.prank(vaultMinterKeeper1); VaultMinter(ilkInst.vaultMinter).wipe(); + vm.prank(facilitator1); VaultMinter(ilkFunnelInst.vaultMinter).setConfig(-1, 1 hours, uint96(1_000 * WAD)); + vm.prank(vaultMinterKeeper1); VaultMinter(ilkFunnelInst.vaultMinter).wipe(); } function testSwapFromFacilitator() public { @@ -366,8 +381,8 @@ contract DeploymentTest is DssTest { deal(address(dss.dai), ilkInst.buffer, 1_000 * WAD); - vm.prank(allocatorProxy); Swapper(ilkInst.swapper).setLimits(address(dss.dai), USDC, uint96(1_000 * WAD), 1 hours); - vm.prank(facilitator1); Swapper(ilkInst.swapper).swap(address(dss.dai), USDC, 1_000 * WAD, 990 * 10**6 , uniV3Callee, daiUsdcPath); + vm.prank(allocatorProxy); Swapper(ilkFunnelInst.swapper).setLimits(address(dss.dai), USDC, uint96(1_000 * WAD), 1 hours); + vm.prank(facilitator1); Swapper(ilkFunnelInst.swapper).swap(address(dss.dai), USDC, 1_000 * WAD, 990 * 10**6 , uniV3Callee, daiUsdcPath); } function testSwapFromKeeper() public { @@ -375,9 +390,9 @@ contract DeploymentTest is DssTest { deal(address(dss.dai), ilkInst.buffer, 1_000 * WAD); - vm.prank(allocatorProxy); Swapper(ilkInst.swapper).setLimits(address(dss.dai), USDC, uint96(1_000 * WAD), 1 hours); - vm.prank(facilitator1); StableSwapper(ilkInst.stableSwapper).setConfig(address(dss.dai), USDC, 1, 1 hours, uint96(1_000 * WAD), uint96(990 * 10**6)); - vm.prank(stableSwapperKeeper1); StableSwapper(ilkInst.stableSwapper).swap(address(dss.dai), USDC, 990 * 10**6, uniV3Callee, daiUsdcPath); + vm.prank(allocatorProxy); Swapper(ilkFunnelInst.swapper).setLimits(address(dss.dai), USDC, uint96(1_000 * WAD), 1 hours); + vm.prank(facilitator1); StableSwapper(ilkFunnelInst.stableSwapper).setConfig(address(dss.dai), USDC, 1, 1 hours, uint96(1_000 * WAD), uint96(990 * 10**6)); + vm.prank(stableSwapperKeeper1); StableSwapper(ilkFunnelInst.stableSwapper).swap(address(dss.dai), USDC, 990 * 10**6, uniV3Callee, daiUsdcPath); } function testDepositWithdrawCollectFromFacilitator() public { @@ -386,7 +401,7 @@ contract DeploymentTest is DssTest { deal(address(dss.dai), ilkInst.buffer, 1_000 * WAD); deal(USDC, ilkInst.buffer, 1_000 * 10**6); - vm.prank(allocatorProxy); DepositorUniV3(ilkInst.depositorUniV3).setLimits(address(dss.dai), USDC, uint24(100), uint96(2_000 * WAD), uint96(2_000 * 10**6), 1 hours); + vm.prank(allocatorProxy); DepositorUniV3(ilkFunnelInst.depositorUniV3).setLimits(address(dss.dai), USDC, uint24(100), uint96(2_000 * WAD), uint96(2_000 * 10**6), 1 hours); DepositorUniV3.LiquidityParams memory dp = DepositorUniV3.LiquidityParams({ gem0 : address(dss.dai), gem1 : USDC, @@ -400,8 +415,8 @@ contract DeploymentTest is DssTest { amt1Min : 900 * 10**6 }); - vm.prank(facilitator1); DepositorUniV3(ilkInst.depositorUniV3).deposit(dp); - vm.prank(facilitator1); DepositorUniV3(ilkInst.depositorUniV3).withdraw(dp, false); + vm.prank(facilitator1); DepositorUniV3(ilkFunnelInst.depositorUniV3).deposit(dp); + vm.prank(facilitator1); DepositorUniV3(ilkFunnelInst.depositorUniV3).withdraw(dp, false); DepositorUniV3.CollectParams memory cp = DepositorUniV3.CollectParams({ gem0 : address(dss.dai), @@ -412,7 +427,7 @@ contract DeploymentTest is DssTest { }); vm.expectRevert(bytes("NP")); // we make sure it reverts since no fees to collect and not because the call is unauthorized - vm.prank(facilitator1); DepositorUniV3(ilkInst.depositorUniV3).collect(cp); + vm.prank(facilitator1); DepositorUniV3(ilkFunnelInst.depositorUniV3).collect(cp); } function testDepositWithdrawCollectFromKeeper() public { @@ -421,16 +436,16 @@ contract DeploymentTest is DssTest { deal(address(dss.dai), ilkInst.buffer, 1_000 * WAD); deal(USDC, ilkInst.buffer, 1_000 * 10**6); - vm.prank(allocatorProxy); DepositorUniV3(ilkInst.depositorUniV3).setLimits(address(dss.dai), USDC, uint24(100), uint96(2_000 * WAD), uint96(2_000 * 10**6), 1 hours); + vm.prank(allocatorProxy); DepositorUniV3(ilkFunnelInst.depositorUniV3).setLimits(address(dss.dai), USDC, uint24(100), uint96(2_000 * WAD), uint96(2_000 * 10**6), 1 hours); - vm.prank(facilitator1); StableDepositorUniV3(ilkInst.stableDepositorUniV3).setConfig(address(dss.dai), USDC, uint24(100), REF_TICK - 100, REF_TICK + 100, 1, 1 hours, uint96(1_000 * WAD), uint96(1000 * 10**6), 0, 0); - vm.prank(stableDepositorUniV3Keeper1); StableDepositorUniV3(ilkInst.stableDepositorUniV3).deposit(address(dss.dai), USDC, uint24(100), REF_TICK - 100, REF_TICK + 100, 0, 0); + vm.prank(facilitator1); StableDepositorUniV3(ilkFunnelInst.stableDepositorUniV3).setConfig(address(dss.dai), USDC, uint24(100), REF_TICK - 100, REF_TICK + 100, 1, 1 hours, uint96(1_000 * WAD), uint96(1000 * 10**6), 0, 0); + vm.prank(stableDepositorUniV3Keeper1); StableDepositorUniV3(ilkFunnelInst.stableDepositorUniV3).deposit(address(dss.dai), USDC, uint24(100), REF_TICK - 100, REF_TICK + 100, 0, 0); - vm.prank(facilitator1); StableDepositorUniV3(ilkInst.stableDepositorUniV3).setConfig(address(dss.dai), USDC, uint24(100), REF_TICK - 100, REF_TICK + 100, -1, 1 hours, uint96(1_000 * WAD), uint96(1000 * 10**6), 0, 0); - vm.prank(stableDepositorUniV3Keeper1); StableDepositorUniV3(ilkInst.stableDepositorUniV3).withdraw(address(dss.dai), USDC, uint24(100), REF_TICK - 100, REF_TICK + 100, 0, 0); + vm.prank(facilitator1); StableDepositorUniV3(ilkFunnelInst.stableDepositorUniV3).setConfig(address(dss.dai), USDC, uint24(100), REF_TICK - 100, REF_TICK + 100, -1, 1 hours, uint96(1_000 * WAD), uint96(1000 * 10**6), 0, 0); + vm.prank(stableDepositorUniV3Keeper1); StableDepositorUniV3(ilkFunnelInst.stableDepositorUniV3).withdraw(address(dss.dai), USDC, uint24(100), REF_TICK - 100, REF_TICK + 100, 0, 0); vm.expectRevert(bytes("NP")); // Reverts since no fees to collect and not because the call is unauthorized - vm.prank(stableDepositorUniV3Keeper1); StableDepositorUniV3(ilkInst.stableDepositorUniV3).collect(address(dss.dai), USDC, uint24(100), REF_TICK - 100, REF_TICK + 100); + vm.prank(stableDepositorUniV3Keeper1); StableDepositorUniV3(ilkFunnelInst.stableDepositorUniV3).collect(address(dss.dai), USDC, uint24(100), REF_TICK - 100, REF_TICK + 100); } function testMoveFromKeeper() public { @@ -441,10 +456,10 @@ contract DeploymentTest is DssTest { // Give conduit1 some funds deal(USDC, ilkInst.buffer, 3_000 * 10**6, true); - vm.prank(ilkInst.conduitMover); AllocatorConduitMock(conduit1).deposit(ILK, USDC, 3_000 * 10**6); + vm.prank(ilkFunnelInst.conduitMover); AllocatorConduitMock(conduit1).deposit(ILK, USDC, 3_000 * 10**6); - vm.prank(facilitator1); ConduitMover(ilkInst.conduitMover).setConfig(conduit1, conduit2, USDC, 1, 1 hours, 3_000 * 10**6); - vm.prank(conduitMoverKeeper1); ConduitMover(ilkInst.conduitMover).move(conduit1, conduit2, USDC); + vm.prank(facilitator1); ConduitMover(ilkFunnelInst.conduitMover).setConfig(conduit1, conduit2, USDC, 1, 1 hours, 3_000 * 10**6); + vm.prank(conduitMoverKeeper1); ConduitMover(ilkFunnelInst.conduitMover).move(conduit1, conduit2, USDC); } function testEndCage() public {