Skip to content

Commit

Permalink
Split deploy/init scripts into core components and default funnels (#78)
Browse files Browse the repository at this point in the history
* split deploy/init scripts into core components and default funnels

* review fixes
  • Loading branch information
hexonaut authored Aug 22, 2024
1 parent 6304bfd commit d941bae
Show file tree
Hide file tree
Showing 4 changed files with 215 additions and 175 deletions.
40 changes: 26 additions & 14 deletions deploy/AllocatorDeploy.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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);
Expand All @@ -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;
}
}
169 changes: 89 additions & 80 deletions deploy/AllocatorInit.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -143,7 +149,6 @@ struct AllocatorIlkConfig {
address[] conduitMoverKeepers;
address[] swapTokens;
address[] depositTokens;
address ilkRegistry;
address uniV3Factory;
}

Expand Down Expand Up @@ -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,
Expand All @@ -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);
Expand All @@ -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)
});
}
}
Loading

0 comments on commit d941bae

Please sign in to comment.