diff --git a/script/Deploy.sol b/script/Deploy.sol index ff66b20..beddd40 100644 --- a/script/Deploy.sol +++ b/script/Deploy.sol @@ -17,6 +17,7 @@ contract Deploy is Script { Dexorder dexorder = new Dexorder(); IRouter router = new ArbitrumRouter(); FeeManager feeManager = FeeManagerLib.debugFeeManager( + payable(msg.sender), payable(msg.sender), payable(0x90F79bf6EB2c4f870365E785982E1f101E93b906), // order fees (native) => dev account #3 (fee=three) payable(0x976EA74026E726554dB657fA54763abd0C3a0aa9), // gas fees (native) => dev account #6 (g=6) diff --git a/script/DeployArbitrum.sol b/script/DeployArbitrum.sol index e204bc1..519e763 100644 --- a/script/DeployArbitrum.sol +++ b/script/DeployArbitrum.sol @@ -13,6 +13,7 @@ import "../src/core/Router.sol"; contract DeployArbitrum is Script { function run() external { address admin = address(0x12DB90820DAFed100E40E21128E40Dcd4fF6B331); + address adjuster = address(0x822e57D95444f9Bf373827950068A877F7C7F5FC); address payable orderFeeAccount = payable(0x078E0C1112262433375b9aaa987BfF09a08e863C); address payable gasFeeAccount = payable(0x411c418C005EBDefB551e5E6B734520Ef2591f51); address payable fillFeeAccount = payable(0x152a3a04cE063dC77497aA06b6A09FeFD271E716); @@ -22,7 +23,7 @@ contract DeployArbitrum is Script { Dexorder dexorder = new Dexorder(); IRouter router = new ArbitrumRouter(); - FeeManager feeManager = FeeManagerLib.defaultFeeManager(admin, orderFeeAccount, gasFeeAccount, fillFeeAccount); + FeeManager feeManager = FeeManagerLib.defaultFeeManager(admin, adjuster, orderFeeAccount, gasFeeAccount, fillFeeAccount); VaultImpl impl = new VaultImpl(router, feeManager, WETH); VaultFactory factory = new VaultFactory(admin, address(impl), 24 * 60 * 60); // 24-hour upgrade notice QueryHelper query = new QueryHelper(UniswapV3Arbitrum.factory); diff --git a/src/core/FeeManager.sol b/src/core/FeeManager.sol index 7e8f532..3496153 100644 --- a/src/core/FeeManager.sol +++ b/src/core/FeeManager.sol @@ -68,6 +68,7 @@ contract FeeManager is IFeeManager { address public immutable override admin; + address public override adjuster; address payable public override orderFeeAccount; address payable public override gasFeeAccount; @@ -83,6 +84,7 @@ contract FeeManager is IFeeManager { FeeSchedule limits; address admin; + address adjuster; address payable orderFeeAccount; address payable gasFeeAccount; address payable fillFeeAccount; @@ -127,6 +129,12 @@ contract FeeManager is IFeeManager { } + modifier onlyAdminOrAdjuster() { + require(msg.sender == admin || msg.sender == adjuster, "not admin or adjuster"); + _; + } + + function _push() internal { // if existing proposals have become active, set them as the main schedules. if (proposedLimitActivationTime != 0 && proposedLimitActivationTime <= block.timestamp) { @@ -155,7 +163,7 @@ contract FeeManager is IFeeManager { } - function setFees(FeeSchedule calldata sched) public override onlyAdmin { + function setFees(FeeSchedule calldata sched) public override onlyAdminOrAdjuster { _push(); // check limits @@ -187,10 +195,12 @@ contract FeeManager is IFeeManager { function setFeeAccounts( + address adjuster_, address payable fillFeeAccount_, address payable orderFeeAccount_, address payable gasFeeAccount_ ) public override onlyAdmin { + adjuster = adjuster_; fillFeeAccount = fillFeeAccount_; orderFeeAccount = orderFeeAccount_; gasFeeAccount = gasFeeAccount_; diff --git a/src/interface/IFeeManager.sol b/src/interface/IFeeManager.sol index a0effb8..de7d1b2 100644 --- a/src/interface/IFeeManager.sol +++ b/src/interface/IFeeManager.sol @@ -43,19 +43,23 @@ interface IFeeManager { // The admin account may change the fees, limits, and fee account addresses. function admin() external view returns (address); + // The adjuster account may change the fees. + function adjuster() external view returns (address); + // The three fee types are each sent to a separate address for accounting. function orderFeeAccount() external view returns (address payable); function gasFeeAccount() external view returns (address payable); function fillFeeAccount() external view returns (address payable); - // The admin may change the fees within the limits after only a short delay + // The admin or the adjuster may change the fees within the limits after only a short delay function setFees(FeeSchedule calldata sched) external; - // The admin may change the fee limits themselves after a long delay + // Only the admin may change the fee limits themselves after a long delay function setLimits(FeeSchedule calldata sched) external; // The admin may adjust the destination of fees at any time function setFeeAccounts( + address adjuster, address payable fillFeeAccount, address payable orderFeeAccount, address payable gasFeeAccount diff --git a/src/more/FeeManagerLib.sol b/src/more/FeeManagerLib.sol index 76abfb7..ceaea12 100644 --- a/src/more/FeeManagerLib.sol +++ b/src/more/FeeManagerLib.sol @@ -12,12 +12,13 @@ library FeeManagerLib { function defaultFeeManager(address payable owner) internal returns (FeeManager) { - return FeeManagerLib.defaultFeeManager(owner, owner, owner, owner); + return FeeManagerLib.defaultFeeManager(owner, owner, owner, owner, owner); } function defaultFeeManager( address admin, + address adjuster, address payable orderFeeAccount, address payable gasFeeAccount, address payable fillFeeAccount @@ -47,7 +48,7 @@ library FeeManagerLib { ); FeeManager.ConstructorArgs memory args = FeeManager.ConstructorArgs( limitChangeNoticeDuration, feeChangeNoticeDuration, maxIncreaseOrderFeePct, maxIncreaseTrancheFeePct, - fees, limits, admin, orderFeeAccount, gasFeeAccount, fillFeeAccount + fees, limits, admin, adjuster, orderFeeAccount, gasFeeAccount, fillFeeAccount ); return new FeeManager(args); } @@ -60,12 +61,13 @@ library FeeManagerLib { function freeFeeManager(address payable owner) internal returns (FeeManager) { - return FeeManagerLib.freeFeeManager(owner, owner, owner, owner); + return FeeManagerLib.freeFeeManager(owner, owner, owner, owner, owner); } function freeFeeManager( address admin, + address adjuster, address payable orderFeeAccount, address payable gasFeeAccount, address payable fillFeeAccount @@ -94,7 +96,7 @@ library FeeManagerLib { ); FeeManager.ConstructorArgs memory args = FeeManager.ConstructorArgs( limitChangeNoticeDuration, feeChangeNoticeDuration, maxIncreaseOrderFeePct, maxIncreaseTrancheFeePct, - fees, limits, admin, orderFeeAccount, gasFeeAccount, fillFeeAccount + fees, limits, admin, adjuster, orderFeeAccount, gasFeeAccount, fillFeeAccount ); return new FeeManager(args); } @@ -106,12 +108,13 @@ library FeeManagerLib { function debugFeeManager(address payable owner) internal returns (FeeManager) { - return FeeManagerLib.debugFeeManager(owner, owner, owner, owner); + return FeeManagerLib.debugFeeManager(owner, owner, owner, owner, owner); } function debugFeeManager( address admin, + address adjuster, address payable orderFeeAccount, address payable gasFeeAccount, address payable fillFeeAccount @@ -143,7 +146,7 @@ library FeeManagerLib { ); FeeManager.ConstructorArgs memory args = FeeManager.ConstructorArgs( limitChangeNoticeDuration, feeChangeNoticeDuration, maxIncreaseOrderFeePct, maxIncreaseTrancheFeePct, - fees, limits, admin, orderFeeAccount, gasFeeAccount, fillFeeAccount + fees, limits, admin, adjuster, orderFeeAccount, gasFeeAccount, fillFeeAccount ); return new FeeManager(args); } diff --git a/src/more/VaultAddress.sol b/src/more/VaultAddress.sol index f23c08c..28da8c7 100644 --- a/src/more/VaultAddress.sol +++ b/src/more/VaultAddress.sol @@ -6,7 +6,7 @@ import "@forge-std/console2.sol"; library VaultAddress { // keccak-256 hash of the Vault's bytecode (not the deployed bytecode but the initialization bytecode) - bytes32 public constant VAULT_INIT_CODE_HASH = 0xe5e6257bee9f182ff5b35a3356108ff2bc9bb2ac3017abc40a342f8d338d4d77; + bytes32 public constant VAULT_INIT_CODE_HASH = 0x8b1347850b0b1f2e05548c065af07c78f2c0617f70a2915b3cb7e0ba1bd20630; // the contract being constructed must not have any constructor arguments or the determinism will be broken. // instead, use a callback to get construction arguments