Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
182 changes: 169 additions & 13 deletions script/03_UnificationProposal.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,40 +8,168 @@ import {IUniswapV3Factory} from "briefcase/protocols/v3-core/interfaces/IUniswap
import {IERC20} from "forge-std/interfaces/IERC20.sol";

contract UnificationProposal is Script {
// TODO: Fill in these values
address public constant AGREEMENT_ANCHOR_1 = address(0);
bytes32 public constant CONTENT_HASH_1 = bytes32(0);
address public constant AGREEMENT_ANCHOR_2 = address(0);
bytes32 public constant CONTENT_HASH_2 = bytes32(0);
string public constant PROPOSAL_DESCRIPTION = "";

IGovernorBravo internal constant GOVERNOR_BRAVO =
IGovernorBravo(0x408ED6354d4973f66138C91495F2f2FCbd8724C3);
IERC20 UNI = IERC20(0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984);
IUniswapV2Factory public V2_FACTORY =
IUniswapV2Factory(0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f);
IUniswapV3Factory public constant V3_FACTORY =
IUniswapV3Factory(0x1F98431c8aD98523631AE4a59f267346ea31F984);
address public constant OLD_FEE_TO_SETTER = 0x18e433c7Bf8A2E1d0197CE5d8f9AFAda1A771360;

// EAS Constants
IEAS internal constant EAS = IEAS(0xA1207F3BBa224E2c9c3c6D5aF63D0eb1582Ce587);
bytes32 public constant AGREEMENT_SCHEMA_UID =
0x504f10498bcdb19d4960412dbade6fa1530b8eed65c319f15cbe20fadafe56bd;

function setUp() public {}

function run(MainnetDeployer deployer) public {
vm.startBroadcast();
_run(deployer);
(
address[] memory targets,
uint256[] memory values,
string[] memory signatures,
bytes[] memory calldatas
) = _run(deployer);
console.log("Calldata details:");
for (uint256 i = 0; i < calldatas.length; i++) {
console.log("Target", i);
console.log(targets[i]);
console.log("Value", i);
console.log(values[i]);
console.log("Signature", i);
console.log(signatures[i]);
console.log("Calldata", i);
console.logBytes(calldatas[i]);
console.log("--------------------------------");
}

console.log("Description:");
console.log(PROPOSAL_DESCRIPTION);

bytes memory proposalCalldata = abi.encodeCall(
IGovernorBravo.propose, (targets, values, signatures, calldatas, PROPOSAL_DESCRIPTION)
);
console.log("GovernorBravo.propose() Calldata:");
console.logBytes(proposalCalldata);

GOVERNOR_BRAVO.propose(targets, values, signatures, calldatas, PROPOSAL_DESCRIPTION);

vm.stopBroadcast();
}

function runPranked(MainnetDeployer deployer) public {
vm.startPrank(V3_FACTORY.owner());
_run(deployer);
(
address[] memory targets,
uint256[] memory values,
string[] memory signatures,
bytes[] memory calldatas
) = _run(deployer);
for (uint256 i = 0; i < targets.length; i++) {
targets[i].call{value: values[i]}(calldatas[i]);
}
vm.stopPrank();
}

function _run(MainnetDeployer deployer) public {
function _run(MainnetDeployer deployer)
public
returns (
address[] memory targets,
uint256[] memory values,
string[] memory signatures,
bytes[] memory calldatas
)
{
address timelock = deployer.V3_FACTORY().owner();

// Burn 100M UNI
UNI.transfer(address(0xdead), 100_000_000 ether);
// Enable UniswapV3 FeeAdapter
V3_FACTORY.setOwner(address(deployer.V3_FEE_ADAPTER()));
// Make governance timelock the feeToSetter for UniswapV2
IFeeToSetter(OLD_FEE_TO_SETTER).setFeeToSetter(timelock);
// Set TokenJar as the UniswapV2 fee recipient
V2_FACTORY.setFeeTo(address(deployer.TOKEN_JAR()));
// Approve 40M UNI to UNIVesting contract
UNI.approve(address(deployer.UNI_VESTING()), 40_000_000 ether);
// --- Proposal Actions Setup ---
address[] memory targets = new address[](5);
uint256[] memory values = new uint256[](5);
string[] memory signatures = new string[](5);
bytes[] memory calldatas = new bytes[](5);

// Action 0: Burn 100M UNI
targets[0] = address(UNI);
values[0] = 0;
signatures[0] = "";
calldatas[0] = abi.encodeCall(UNI.transfer, (address(0xdead), 100_000_000 ether));

// Action 1: Enable UniswapV3 FeeAdapter
targets[1] = address(V3_FACTORY);
values[1] = 0;
signatures[1] = "";
calldatas[1] = abi.encodeCall(V3_FACTORY.setOwner, (address(deployer.V3_FEE_ADAPTER())));

// Action 2: Make governance timelock the feeToSetter for UniswapV2
targets[2] = address(OLD_FEE_TO_SETTER);
values[2] = 0;
signatures[2] = "";
calldatas[2] = abi.encodeCall(IFeeToSetter.setFeeToSetter, (timelock));

// Action 3: Set TokenJar as the UniswapV2 fee recipient
targets[3] = address(V2_FACTORY);
values[3] = 0;
signatures[3] = "";
calldatas[3] = abi.encodeCall(V2_FACTORY.setFeeTo, (address(deployer.TOKEN_JAR())));

// Action 4: Approve 40M UNI to UNIVesting contract
targets[4] = address(UNI);
values[4] = 0;
signatures[4] = "";
calldatas[4] = abi.encodeCall(UNI.approve, (address(deployer.UNI_VESTING()), 40_000_000 ether));

// Action 5: Attest to Agreement 1
if (AGREEMENT_ANCHOR_1 != address(0)) {
targets[5] = address(EAS);
values[5] = 0;
signatures[5] = "";
calldatas[5] = abi.encodeCall(
EAS.attest,
(AttestationRequest({
schema: AGREEMENT_SCHEMA_UID,
data: AttestationRequestData({
recipient: AGREEMENT_ANCHOR_1,
expirationTime: 0,
revocable: false,
refUID: bytes32(0),
data: abi.encode(CONTENT_HASH_1),
value: 0
})
}))
);
}

// Action 6: Attest to Agreement 2
if (AGREEMENT_ANCHOR_2 != address(0)) {
targets[6] = address(EAS);
values[6] = 0;
signatures[6] = "";
calldatas[6] = abi.encodeCall(
EAS.attest,
(AttestationRequest({
schema: AGREEMENT_SCHEMA_UID,
data: AttestationRequestData({
recipient: AGREEMENT_ANCHOR_2,
expirationTime: 0,
revocable: false,
refUID: bytes32(0),
data: abi.encode(CONTENT_HASH_2),
value: 0
})
}))
);
}

return (targets, values, signatures, calldatas);
}
}

Expand All @@ -51,3 +179,31 @@ contract UnificationProposal is Script {
interface IFeeToSetter {
function setFeeToSetter(address) external;
}

struct AttestationRequestData {
address recipient;
uint64 expirationTime;
bool revocable;
bytes32 refUID;
bytes data;
uint256 value;
}

struct AttestationRequest {
bytes32 schema;
AttestationRequestData data;
}

interface IEAS {
function attest(AttestationRequest calldata request) external payable returns (bytes32);
}

interface IGovernorBravo {
function propose(
address[] memory targets,
uint256[] memory values,
string[] memory signatures,
bytes[] memory calldatas,
string memory description
) external returns (uint256);
}
Loading