-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* A script to set a new v3 factory owner * A script to set protocol fees on select pools
- Loading branch information
1 parent
d745dd2
commit 02d9ffa
Showing
12 changed files
with
497 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
MAINNET_RPC_URL= | ||
FOUNDRY_PROFILE=default | ||
DEPLOYER_PRIVATE_KEY= | ||
PROPOSER_ADDRESS= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
// SPDX-License-Identifier: AGPL-3.0-only | ||
pragma solidity ^0.8.23; | ||
|
||
import {Script} from "forge-std/Script.sol"; | ||
|
||
import {DeployInput} from "script/DeployInput.sol"; | ||
import {GovernorBravoDelegate} from "script/interfaces/GovernorBravoInterfaces.sol"; | ||
|
||
contract ProposeFactorySetOwner is Script, DeployInput { | ||
GovernorBravoDelegate constant GOVERNOR = GovernorBravoDelegate(UNISWAP_GOVERNOR); | ||
// The default proposer is uf.eek.eth. | ||
address _proposer = | ||
vm.envOr("PROPOSER_ADDRESS", address(0x0459f41c5f09BF678D9C07331894dE31d8C22255)); | ||
|
||
/// @param _newV3FactoryOwner The new factory owner, i.e. the recently deployed `V3FactoryOwner`. | ||
function proposeFactoryOwnerChangeOnGovernor(address _newV3FactoryOwner) | ||
internal | ||
returns (uint256 _proposalId) | ||
{ | ||
address[] memory _targets = new address[](1); | ||
uint256[] memory _values = new uint256[](1); | ||
string[] memory _signatures = new string[](1); | ||
bytes[] memory _calldatas = new bytes[](1); | ||
|
||
_targets[0] = UNISWAP_V3_FACTORY_ADDRESS; | ||
_values[0] = 0; | ||
_signatures[0] = "setOwner(address)"; | ||
_calldatas[0] = abi.encode(address(_newV3FactoryOwner)); | ||
|
||
return GOVERNOR.propose( | ||
_targets, _values, _signatures, _calldatas, "Change Uniswap V3 factory owner" | ||
); | ||
} | ||
|
||
/// @param _newV3FactoryOwner The new factory owner, i.e. the recently deployed `V3FactoryOwner`. | ||
/// @dev After the UniStaker and V3FactoryOwner contracts are deployed, a delegate should run this | ||
/// script to create a proposal to change the Uniswap v3 factory owner. | ||
function run(address _newV3FactoryOwner) public returns (uint256 _proposalId) { | ||
// The expectation is the key loaded here corresponds to the address of the `proposer` above. | ||
// When running as a script, broadcast will fail if the key is not correct. | ||
uint256 _proposerKey = vm.envOr( | ||
"PROPOSER_PRIVATE_KEY", | ||
uint256(0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d) | ||
); | ||
vm.rememberKey(_proposerKey); | ||
|
||
vm.startBroadcast(_proposer); | ||
_proposalId = proposeFactoryOwnerChangeOnGovernor(_newV3FactoryOwner); | ||
vm.stopBroadcast(); | ||
return _proposalId; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
// SPDX-License-Identifier: AGPL-3.0-only | ||
pragma solidity ^0.8.23; | ||
|
||
import {Script} from "forge-std/Script.sol"; | ||
|
||
import {DeployInput} from "script/DeployInput.sol"; | ||
import {GovernorBravoDelegate} from "script/interfaces/GovernorBravoInterfaces.sol"; | ||
|
||
/// @dev A new proposal script that updates a pool's fee settings should inherit this abstract | ||
/// script and implement `getPoolFeeSettings`. | ||
abstract contract ProposeProtocolFeesBase is Script, DeployInput { | ||
GovernorBravoDelegate constant GOVERNOR = GovernorBravoDelegate(UNISWAP_GOVERNOR); | ||
// The default proposer is uf.eek.eth. | ||
address _proposer = | ||
vm.envOr("PROPOSER_ADDRESS", address(0x0459f41c5f09BF678D9C07331894dE31d8C22255)); | ||
|
||
/// @dev The targets for the proposal which should be the `V3FactoryOwner`. | ||
address[] public targets; | ||
/// @dev The values to pass into the proposal which should all be 0. | ||
uint256[] public values; | ||
/// @dev The function signatures that will be called when a proposal is executed. All of the | ||
/// signatures should be `setFeeProtocol(address,uint8,uint8)`. | ||
string[] public signatures; | ||
/// @dev The calldata for all of function calls in the proposal. These should match the | ||
/// `PoolFeeSettings` defined in `getPoolFeeSettings`. | ||
bytes[] public calldatas; | ||
|
||
/// @dev A struct to represent all of the information needed to update a pool's fees. Such as the | ||
/// target pool and the new fees for each token in the pool. | ||
struct PoolFeeSettings { | ||
address pool; | ||
uint8 feeProtocol0; | ||
uint8 feeProtocol1; | ||
} | ||
|
||
/// @dev A utility function that updates the targets, values, signatures, and calldatas for a | ||
/// proposal that will only update protocol fees for a list of pools. | ||
function pushFeeSettingToProposalCalldata( | ||
address _v3FactoryOwner, | ||
address _pool, | ||
uint8 _feeProtocol0, | ||
uint8 _feeProtocol1 | ||
) internal { | ||
targets.push(_v3FactoryOwner); | ||
values.push(0); | ||
signatures.push("setFeeProtocol(address,uint8,uint8)"); | ||
calldatas.push(abi.encode(_pool, _feeProtocol0, _feeProtocol1)); | ||
} | ||
|
||
/// @return A list of pool settings used to update protocol fees for each pool. | ||
/// @dev A new `ProposeProtocolFees` script should extend this base script and only implement this | ||
/// function to return a list of pools to be updated with their new settings. This function will | ||
/// return the appropriate pool settings in the `run` method and add them to the proposal that | ||
/// will be proposed. | ||
function getPoolFeeSettings() internal pure virtual returns (PoolFeeSettings[] memory); | ||
|
||
/// @dev Create a proposal on the Uniswap Governor with targets, values, signatures, and calldatas | ||
/// defined in this contracts. These values should have been built using | ||
/// `pushFeeSettingToProposalCalldata`. | ||
function propose() internal returns (uint256 _proposalId) { | ||
return GOVERNOR.propose( | ||
targets, | ||
values, | ||
signatures, | ||
calldatas, | ||
"Change Uniswap V3 factory owner and set pool protocol fees" | ||
); | ||
} | ||
|
||
/// @param _newV3FactoryOwner The new factory owner which should have be the recently deployed. | ||
/// @dev This script sets protocol fees for whatever pools and fees are configured. This script | ||
/// should only be run after `UniStaker` and the `V3FactoryOwner` are deployed, and after the | ||
/// `V3FactoryOwner` becomes the owner of ther Uniswap v3 factory. | ||
function run(address _newV3FactoryOwner) public returns (uint256 _proposalId) { | ||
// The expectation is the key loaded here corresponds to the address of the `proposer` above. | ||
// When running as a script, broadcast will fail if the key is not correct. | ||
uint256 _proposerKey = vm.envUint("PROPOSER_PRIVATE_KEY"); | ||
vm.rememberKey(_proposerKey); | ||
|
||
PoolFeeSettings[] memory poolFeeSettings = getPoolFeeSettings(); | ||
for (uint256 i = 0; i < poolFeeSettings.length; i++) { | ||
pushFeeSettingToProposalCalldata( | ||
_newV3FactoryOwner, | ||
poolFeeSettings[i].pool, | ||
poolFeeSettings[i].feeProtocol0, | ||
poolFeeSettings[i].feeProtocol1 | ||
); | ||
} | ||
|
||
vm.startBroadcast(_proposer); | ||
_proposalId = propose(); | ||
vm.stopBroadcast(); | ||
return _proposalId; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
// SPDX-License-Identifier: AGPL-3.0-only | ||
pragma solidity ^0.8.23; | ||
|
||
import {Script} from "forge-std/Script.sol"; | ||
|
||
import {DeployInput} from "script/DeployInput.sol"; | ||
import {GovernorBravoDelegate} from "script/interfaces/GovernorBravoInterfaces.sol"; | ||
import {ProposeProtocolFeesBase} from "script/ProposeProtocolFeesBase.s.sol"; | ||
|
||
/// @dev This script will turn on protocol fees for the following pools: WBTC-WETH-3000, | ||
/// DAI-WETH-300, and DAI-USDC-100. | ||
contract ProposeProtocolFeesBatch1 is ProposeProtocolFeesBase { | ||
// TODO Double check these are the right pools | ||
address constant WBTC_WETH_3000_POOL = 0xCBCdF9626bC03E24f779434178A73a0B4bad62eD; | ||
address constant DAI_WETH_3000_POOL = 0xC2e9F25Be6257c210d7Adf0D4Cd6E3E881ba25f8; | ||
address constant DAI_USDC_100_POOL = 0x5777d92f208679DB4b9778590Fa3CAB3aC9e2168; | ||
|
||
/// @return A list of pool settings used to update protocol fees for each pool. | ||
function getPoolFeeSettings() internal pure override returns (PoolFeeSettings[] memory) { | ||
PoolFeeSettings[] memory poolFeeSettings = new PoolFeeSettings[](3); | ||
poolFeeSettings[0] = PoolFeeSettings(WBTC_WETH_3000_POOL, 10, 10); | ||
poolFeeSettings[1] = PoolFeeSettings(DAI_WETH_3000_POOL, 10, 10); | ||
poolFeeSettings[2] = PoolFeeSettings(DAI_USDC_100_POOL, 10, 10); | ||
return poolFeeSettings; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
// SPDX-License-Identifier: AGPL-3.0-only | ||
pragma solidity ^0.8.23; | ||
|
||
// This interface was created using cast interface. The contract can be found at | ||
// https://etherscan.io/address/0x53a328f4086d7c0f1fa19e594c9b842125263026#code#F2#L182 | ||
|
||
interface GovernorBravoDelegate { | ||
type ProposalState is uint8; | ||
|
||
struct Receipt { | ||
bool hasVoted; | ||
uint8 support; | ||
uint96 votes; | ||
} | ||
|
||
event NewAdmin(address oldAdmin, address newAdmin); | ||
event NewImplementation(address oldImplementation, address newImplementation); | ||
event NewPendingAdmin(address oldPendingAdmin, address newPendingAdmin); | ||
event ProposalCanceled(uint256 id); | ||
event ProposalCreated( | ||
uint256 id, | ||
address proposer, | ||
address[] targets, | ||
uint256[] values, | ||
string[] signatures, | ||
bytes[] calldatas, | ||
uint256 startBlock, | ||
uint256 endBlock, | ||
string description | ||
); | ||
event ProposalExecuted(uint256 id); | ||
event ProposalQueued(uint256 id, uint256 eta); | ||
event ProposalThresholdSet(uint256 oldProposalThreshold, uint256 newProposalThreshold); | ||
event VoteCast( | ||
address indexed voter, uint256 proposalId, uint8 support, uint256 votes, string reason | ||
); | ||
event VotingDelaySet(uint256 oldVotingDelay, uint256 newVotingDelay); | ||
event VotingPeriodSet(uint256 oldVotingPeriod, uint256 newVotingPeriod); | ||
|
||
function BALLOT_TYPEHASH() external view returns (bytes32); | ||
function DOMAIN_TYPEHASH() external view returns (bytes32); | ||
function MAX_PROPOSAL_THRESHOLD() external view returns (uint256); | ||
function MAX_VOTING_DELAY() external view returns (uint256); | ||
function MAX_VOTING_PERIOD() external view returns (uint256); | ||
function MIN_PROPOSAL_THRESHOLD() external view returns (uint256); | ||
function MIN_VOTING_DELAY() external view returns (uint256); | ||
function MIN_VOTING_PERIOD() external view returns (uint256); | ||
function _acceptAdmin() external; | ||
function _initiate(uint256 proposalCount) external; | ||
function _setPendingAdmin(address newPendingAdmin) external; | ||
function _setProposalThreshold(uint256 newProposalThreshold) external; | ||
function _setVotingDelay(uint256 newVotingDelay) external; | ||
function _setVotingPeriod(uint256 newVotingPeriod) external; | ||
function admin() external view returns (address); | ||
function cancel(uint256 proposalId) external; | ||
function castVote(uint256 proposalId, uint8 support) external; | ||
function castVoteBySig(uint256 proposalId, uint8 support, uint8 v, bytes32 r, bytes32 s) external; | ||
function castVoteWithReason(uint256 proposalId, uint8 support, string memory reason) external; | ||
function execute(uint256 proposalId) external payable; | ||
function getActions(uint256 proposalId) | ||
external | ||
view | ||
returns ( | ||
address[] memory targets, | ||
uint256[] memory values, | ||
string[] memory signatures, | ||
bytes[] memory calldatas | ||
); | ||
function getReceipt(uint256 proposalId, address voter) external view returns (Receipt memory); | ||
function implementation() external view returns (address); | ||
function initialProposalId() external view returns (uint256); | ||
function initialize( | ||
address timelock_, | ||
address uni_, | ||
uint256 votingPeriod_, | ||
uint256 votingDelay_, | ||
uint256 proposalThreshold_ | ||
) external; | ||
function latestProposalIds(address) external view returns (uint256); | ||
function name() external view returns (string memory); | ||
function pendingAdmin() external view returns (address); | ||
function proposalCount() external view returns (uint256); | ||
function proposalMaxOperations() external view returns (uint256); | ||
function proposalThreshold() external view returns (uint256); | ||
function proposals(uint256) | ||
external | ||
view | ||
returns ( | ||
uint256 id, | ||
address proposer, | ||
uint256 eta, | ||
uint256 startBlock, | ||
uint256 endBlock, | ||
uint256 forVotes, | ||
uint256 againstVotes, | ||
uint256 abstainVotes, | ||
bool canceled, | ||
bool executed | ||
); | ||
function propose( | ||
address[] memory targets, | ||
uint256[] memory values, | ||
string[] memory signatures, | ||
bytes[] memory calldatas, | ||
string memory description | ||
) external returns (uint256); | ||
function queue(uint256 proposalId) external; | ||
function quorumVotes() external view returns (uint256); | ||
function state(uint256 proposalId) external view returns (ProposalState); | ||
function timelock() external view returns (address); | ||
function uni() external view returns (address); | ||
function votingDelay() external view returns (uint256); | ||
function votingPeriod() external view returns (uint256); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
// SPDX-License-Identifier: AGPL-3.0-only | ||
pragma solidity ^0.8.23; | ||
|
||
contract Constants { | ||
address constant UNISWAP_GOVERNOR_ADDRESS = 0x408ED6354d4973f66138C91495F2f2FCbd8724C3; | ||
address constant WBTC_WETH_3000_POOL = 0xCBCdF9626bC03E24f779434178A73a0B4bad62eD; | ||
address constant DAI_WETH_3000_POOL = 0xC2e9F25Be6257c210d7Adf0D4Cd6E3E881ba25f8; | ||
address constant DAI_USDC_100_POOL = 0x5777d92f208679DB4b9778590Fa3CAB3aC9e2168; | ||
} |
Oops, something went wrong.